diff --git a/pkg/loop/internal/net/broker.go b/pkg/loop/internal/net/broker.go index fe671f0ff..816a673c5 100644 --- a/pkg/loop/internal/net/broker.go +++ b/pkg/loop/internal/net/broker.go @@ -65,13 +65,26 @@ type BrokerConfig struct { type BrokerExt struct { Broker Broker BrokerConfig + + // State management hook for refresh functionality + onRefreshComplete func(ctx context.Context) error + hooksMu sync.RWMutex } // WithName returns a new [*BrokerExt] with Name added to the logger. +// Note: The refresh hook is not shared with the named broker to avoid concurrency issues. func (b *BrokerExt) WithName(name string) *BrokerExt { - bn := *b - bn.Logger = logger.Named(b.Logger, name) - return &bn + return &BrokerExt{ + Broker: b.Broker, + BrokerConfig: BrokerConfig{ + StopCh: b.StopCh, + Logger: logger.Named(b.Logger, name), + GRPCOpts: b.GRPCOpts, + }, + // Don't share the refresh hook - each named broker manages its own + onRefreshComplete: nil, + hooksMu: sync.RWMutex{}, + } } // NewClientConn return a new *clientConn backed by this *BrokerExt. @@ -147,6 +160,25 @@ func (b *BrokerExt) CloseAll(deps ...Resource) { } } +// SetOnRefreshComplete sets a hook to be called after successful connection refresh. +func (b *BrokerExt) SetOnRefreshComplete(hook func(ctx context.Context) error) { + b.hooksMu.Lock() + defer b.hooksMu.Unlock() + b.onRefreshComplete = hook +} + +// executeOnRefreshComplete executes the refresh completion hook if it exists. +func (b *BrokerExt) executeOnRefreshComplete(ctx context.Context) error { + b.hooksMu.RLock() + hook := b.onRefreshComplete + b.hooksMu.RUnlock() + + if hook != nil { + return hook(ctx) + } + return nil +} + type Resource struct { io.Closer Name string diff --git a/pkg/loop/internal/net/client.go b/pkg/loop/internal/net/client.go index fbe5978f6..b623b5455 100644 --- a/pkg/loop/internal/net/client.go +++ b/pkg/loop/internal/net/client.go @@ -128,6 +128,13 @@ func (c *clientConn) refresh(ctx context.Context, orig *grpc.ClientConn) *grpc.C c.CloseAll(c.deps...) return false } + + // Execute refresh completion hook after successful connection + if err := c.BrokerExt.executeOnRefreshComplete(ctx); err != nil { + // Don't fail the refresh, but log the error + c.Logger.Errorw("Refresh completion hook failed", "err", err, "conn", c.name) + } + return true } diff --git a/pkg/loop/internal/pb/ccipocr3/chainaccessor.pb.go b/pkg/loop/internal/pb/ccipocr3/chainaccessor.pb.go index 2ba41826a..762346e21 100644 --- a/pkg/loop/internal/pb/ccipocr3/chainaccessor.pb.go +++ b/pkg/loop/internal/pb/ccipocr3/chainaccessor.pb.go @@ -734,8 +734,8 @@ func (x *GetChainFeePriceUpdateRequest) GetChainSelectors() []uint64 { } type GetChainFeePriceUpdateResponse struct { - state protoimpl.MessageState `protogen:"open.v1"` - FeePriceUpdates map[uint64]*TimestampedBig `protobuf:"bytes,1,rep,name=fee_price_updates,json=feePriceUpdates,proto3" json:"fee_price_updates,omitempty" protobuf_key:"varint,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"` // key is chain selector + state protoimpl.MessageState `protogen:"open.v1"` + FeePriceUpdates map[uint64]*TimestampedUnixBig `protobuf:"bytes,1,rep,name=fee_price_updates,json=feePriceUpdates,proto3" json:"fee_price_updates,omitempty" protobuf_key:"varint,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"` // key is chain selector unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache } @@ -770,7 +770,7 @@ func (*GetChainFeePriceUpdateResponse) Descriptor() ([]byte, []int) { return file_chainaccessor_proto_rawDescGZIP(), []int{15} } -func (x *GetChainFeePriceUpdateResponse) GetFeePriceUpdates() map[uint64]*TimestampedBig { +func (x *GetChainFeePriceUpdateResponse) GetFeePriceUpdates() map[uint64]*TimestampedUnixBig { if x != nil { return x.FeePriceUpdates } @@ -3147,6 +3147,417 @@ func (x *FeeQuoterDestChainConfig) GetChainFamilySelector() []byte { return nil } +// USDCMessageReader request/response messages +type MessagesByTokenIDRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + SourceChainSelector uint64 `protobuf:"varint,1,opt,name=source_chain_selector,json=sourceChainSelector,proto3" json:"source_chain_selector,omitempty"` + DestChainSelector uint64 `protobuf:"varint,2,opt,name=dest_chain_selector,json=destChainSelector,proto3" json:"dest_chain_selector,omitempty"` + Tokens map[string]*RampTokenAmount `protobuf:"bytes,3,rep,name=tokens,proto3" json:"tokens,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"` // key is MessageTokenID string representation + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *MessagesByTokenIDRequest) Reset() { + *x = MessagesByTokenIDRequest{} + mi := &file_chainaccessor_proto_msgTypes[58] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *MessagesByTokenIDRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*MessagesByTokenIDRequest) ProtoMessage() {} + +func (x *MessagesByTokenIDRequest) ProtoReflect() protoreflect.Message { + mi := &file_chainaccessor_proto_msgTypes[58] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use MessagesByTokenIDRequest.ProtoReflect.Descriptor instead. +func (*MessagesByTokenIDRequest) Descriptor() ([]byte, []int) { + return file_chainaccessor_proto_rawDescGZIP(), []int{58} +} + +func (x *MessagesByTokenIDRequest) GetSourceChainSelector() uint64 { + if x != nil { + return x.SourceChainSelector + } + return 0 +} + +func (x *MessagesByTokenIDRequest) GetDestChainSelector() uint64 { + if x != nil { + return x.DestChainSelector + } + return 0 +} + +func (x *MessagesByTokenIDRequest) GetTokens() map[string]*RampTokenAmount { + if x != nil { + return x.Tokens + } + return nil +} + +type MessagesByTokenIDResponse struct { + state protoimpl.MessageState `protogen:"open.v1"` + Messages map[string][]byte `protobuf:"bytes,1,rep,name=messages,proto3" json:"messages,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"` // key is MessageTokenID string representation, value is message bytes + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *MessagesByTokenIDResponse) Reset() { + *x = MessagesByTokenIDResponse{} + mi := &file_chainaccessor_proto_msgTypes[59] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *MessagesByTokenIDResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*MessagesByTokenIDResponse) ProtoMessage() {} + +func (x *MessagesByTokenIDResponse) ProtoReflect() protoreflect.Message { + mi := &file_chainaccessor_proto_msgTypes[59] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use MessagesByTokenIDResponse.ProtoReflect.Descriptor instead. +func (*MessagesByTokenIDResponse) Descriptor() ([]byte, []int) { + return file_chainaccessor_proto_rawDescGZIP(), []int{59} +} + +func (x *MessagesByTokenIDResponse) GetMessages() map[string][]byte { + if x != nil { + return x.Messages + } + return nil +} + +// PriceReader request/response messages +type GetFeedPricesUSDRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + Tokens []string `protobuf:"bytes,1,rep,name=tokens,proto3" json:"tokens,omitempty"` // UnknownEncodedAddress + TokenInfo map[string]*TokenInfo `protobuf:"bytes,2,rep,name=token_info,json=tokenInfo,proto3" json:"token_info,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"` // key is UnknownEncodedAddress + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *GetFeedPricesUSDRequest) Reset() { + *x = GetFeedPricesUSDRequest{} + mi := &file_chainaccessor_proto_msgTypes[60] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *GetFeedPricesUSDRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetFeedPricesUSDRequest) ProtoMessage() {} + +func (x *GetFeedPricesUSDRequest) ProtoReflect() protoreflect.Message { + mi := &file_chainaccessor_proto_msgTypes[60] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetFeedPricesUSDRequest.ProtoReflect.Descriptor instead. +func (*GetFeedPricesUSDRequest) Descriptor() ([]byte, []int) { + return file_chainaccessor_proto_rawDescGZIP(), []int{60} +} + +func (x *GetFeedPricesUSDRequest) GetTokens() []string { + if x != nil { + return x.Tokens + } + return nil +} + +func (x *GetFeedPricesUSDRequest) GetTokenInfo() map[string]*TokenInfo { + if x != nil { + return x.TokenInfo + } + return nil +} + +type GetFeedPricesUSDResponse struct { + state protoimpl.MessageState `protogen:"open.v1"` + Prices map[string]*BigInt `protobuf:"bytes,1,rep,name=prices,proto3" json:"prices,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"` // key is UnknownEncodedAddress, value is price + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *GetFeedPricesUSDResponse) Reset() { + *x = GetFeedPricesUSDResponse{} + mi := &file_chainaccessor_proto_msgTypes[61] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *GetFeedPricesUSDResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetFeedPricesUSDResponse) ProtoMessage() {} + +func (x *GetFeedPricesUSDResponse) ProtoReflect() protoreflect.Message { + mi := &file_chainaccessor_proto_msgTypes[61] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetFeedPricesUSDResponse.ProtoReflect.Descriptor instead. +func (*GetFeedPricesUSDResponse) Descriptor() ([]byte, []int) { + return file_chainaccessor_proto_rawDescGZIP(), []int{61} +} + +func (x *GetFeedPricesUSDResponse) GetPrices() map[string]*BigInt { + if x != nil { + return x.Prices + } + return nil +} + +type GetFeeQuoterTokenUpdatesRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + Tokens []string `protobuf:"bytes,1,rep,name=tokens,proto3" json:"tokens,omitempty"` // UnknownEncodedAddress + ChainSelector uint64 `protobuf:"varint,2,opt,name=chain_selector,json=chainSelector,proto3" json:"chain_selector,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *GetFeeQuoterTokenUpdatesRequest) Reset() { + *x = GetFeeQuoterTokenUpdatesRequest{} + mi := &file_chainaccessor_proto_msgTypes[62] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *GetFeeQuoterTokenUpdatesRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetFeeQuoterTokenUpdatesRequest) ProtoMessage() {} + +func (x *GetFeeQuoterTokenUpdatesRequest) ProtoReflect() protoreflect.Message { + mi := &file_chainaccessor_proto_msgTypes[62] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetFeeQuoterTokenUpdatesRequest.ProtoReflect.Descriptor instead. +func (*GetFeeQuoterTokenUpdatesRequest) Descriptor() ([]byte, []int) { + return file_chainaccessor_proto_rawDescGZIP(), []int{62} +} + +func (x *GetFeeQuoterTokenUpdatesRequest) GetTokens() []string { + if x != nil { + return x.Tokens + } + return nil +} + +func (x *GetFeeQuoterTokenUpdatesRequest) GetChainSelector() uint64 { + if x != nil { + return x.ChainSelector + } + return 0 +} + +type GetFeeQuoterTokenUpdatesResponse struct { + state protoimpl.MessageState `protogen:"open.v1"` + TokenUpdates map[string]*TimestampedUnixBig `protobuf:"bytes,1,rep,name=token_updates,json=tokenUpdates,proto3" json:"token_updates,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"` // key is UnknownEncodedAddress + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *GetFeeQuoterTokenUpdatesResponse) Reset() { + *x = GetFeeQuoterTokenUpdatesResponse{} + mi := &file_chainaccessor_proto_msgTypes[63] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *GetFeeQuoterTokenUpdatesResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetFeeQuoterTokenUpdatesResponse) ProtoMessage() {} + +func (x *GetFeeQuoterTokenUpdatesResponse) ProtoReflect() protoreflect.Message { + mi := &file_chainaccessor_proto_msgTypes[63] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetFeeQuoterTokenUpdatesResponse.ProtoReflect.Descriptor instead. +func (*GetFeeQuoterTokenUpdatesResponse) Descriptor() ([]byte, []int) { + return file_chainaccessor_proto_rawDescGZIP(), []int{63} +} + +func (x *GetFeeQuoterTokenUpdatesResponse) GetTokenUpdates() map[string]*TimestampedUnixBig { + if x != nil { + return x.TokenUpdates + } + return nil +} + +// Helper message types +type MessageTokenID struct { + state protoimpl.MessageState `protogen:"open.v1"` + SeqNr uint64 `protobuf:"varint,1,opt,name=seq_nr,json=seqNr,proto3" json:"seq_nr,omitempty"` + Index int32 `protobuf:"varint,2,opt,name=index,proto3" json:"index,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *MessageTokenID) Reset() { + *x = MessageTokenID{} + mi := &file_chainaccessor_proto_msgTypes[64] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *MessageTokenID) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*MessageTokenID) ProtoMessage() {} + +func (x *MessageTokenID) ProtoReflect() protoreflect.Message { + mi := &file_chainaccessor_proto_msgTypes[64] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use MessageTokenID.ProtoReflect.Descriptor instead. +func (*MessageTokenID) Descriptor() ([]byte, []int) { + return file_chainaccessor_proto_rawDescGZIP(), []int{64} +} + +func (x *MessageTokenID) GetSeqNr() uint64 { + if x != nil { + return x.SeqNr + } + return 0 +} + +func (x *MessageTokenID) GetIndex() int32 { + if x != nil { + return x.Index + } + return 0 +} + +type TokenInfo struct { + state protoimpl.MessageState `protogen:"open.v1"` + AggregatorAddress string `protobuf:"bytes,1,opt,name=aggregator_address,json=aggregatorAddress,proto3" json:"aggregator_address,omitempty"` // UnknownEncodedAddress + DeviationPpb *BigInt `protobuf:"bytes,2,opt,name=deviation_ppb,json=deviationPpb,proto3" json:"deviation_ppb,omitempty"` + Decimals uint32 `protobuf:"varint,3,opt,name=decimals,proto3" json:"decimals,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *TokenInfo) Reset() { + *x = TokenInfo{} + mi := &file_chainaccessor_proto_msgTypes[65] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *TokenInfo) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*TokenInfo) ProtoMessage() {} + +func (x *TokenInfo) ProtoReflect() protoreflect.Message { + mi := &file_chainaccessor_proto_msgTypes[65] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use TokenInfo.ProtoReflect.Descriptor instead. +func (*TokenInfo) Descriptor() ([]byte, []int) { + return file_chainaccessor_proto_rawDescGZIP(), []int{65} +} + +func (x *TokenInfo) GetAggregatorAddress() string { + if x != nil { + return x.AggregatorAddress + } + return "" +} + +func (x *TokenInfo) GetDeviationPpb() *BigInt { + if x != nil { + return x.DeviationPpb + } + return nil +} + +func (x *TokenInfo) GetDecimals() uint32 { + if x != nil { + return x.Decimals + } + return 0 +} + var File_chainaccessor_proto protoreflect.FileDescriptor const file_chainaccessor_proto_rawDesc = "" + @@ -3205,12 +3616,12 @@ const file_chainaccessor_proto_rawDesc = "" + "\x03key\x18\x01 \x01(\x04R\x03key\x129\n" + "\x05value\x18\x02 \x01(\v2#.loop.internal.pb.ccipocr3.NonceMapR\x05value:\x028\x01\"H\n" + "\x1dGetChainFeePriceUpdateRequest\x12'\n" + - "\x0fchain_selectors\x18\x01 \x03(\x04R\x0echainSelectors\"\x8b\x02\n" + + "\x0fchain_selectors\x18\x01 \x03(\x04R\x0echainSelectors\"\x8f\x02\n" + "\x1eGetChainFeePriceUpdateResponse\x12z\n" + - "\x11fee_price_updates\x18\x01 \x03(\v2N.loop.internal.pb.ccipocr3.GetChainFeePriceUpdateResponse.FeePriceUpdatesEntryR\x0ffeePriceUpdates\x1am\n" + + "\x11fee_price_updates\x18\x01 \x03(\v2N.loop.internal.pb.ccipocr3.GetChainFeePriceUpdateResponse.FeePriceUpdatesEntryR\x0ffeePriceUpdates\x1aq\n" + "\x14FeePriceUpdatesEntry\x12\x10\n" + - "\x03key\x18\x01 \x01(\x04R\x03key\x12?\n" + - "\x05value\x18\x02 \x01(\v2).loop.internal.pb.ccipocr3.TimestampedBigR\x05value:\x028\x01\"4\n" + + "\x03key\x18\x01 \x01(\x04R\x03key\x12C\n" + + "\x05value\x18\x02 \x01(\v2-.loop.internal.pb.ccipocr3.TimestampedUnixBigR\x05value:\x028\x01\"4\n" + "\x1bGetLatestPriceSeqNrResponse\x12\x15\n" + "\x06seq_nr\x18\x01 \x01(\x04R\x05seqNr\"\x97\x01\n" + "\x19MsgsBetweenSeqNumsRequest\x12.\n" + @@ -3381,7 +3792,46 @@ const file_chainaccessor_proto_rawDesc = "" + "\x16network_fee_usdc_cents\x18\x0e \x01(\rR\x13networkFeeUsdcCents\x12A\n" + "\x1dgas_price_staleness_threshold\x18\x13 \x01(\rR\x1agasPriceStalenessThreshold\x12/\n" + "\x14enforce_out_of_order\x18\x0f \x01(\bR\x11enforceOutOfOrder\x122\n" + - "\x15chain_family_selector\x18\x10 \x01(\fR\x13chainFamilySelector2\xe3\x0e\n" + + "\x15chain_family_selector\x18\x10 \x01(\fR\x13chainFamilySelector\"\xbe\x02\n" + + "\x18MessagesByTokenIDRequest\x122\n" + + "\x15source_chain_selector\x18\x01 \x01(\x04R\x13sourceChainSelector\x12.\n" + + "\x13dest_chain_selector\x18\x02 \x01(\x04R\x11destChainSelector\x12W\n" + + "\x06tokens\x18\x03 \x03(\v2?.loop.internal.pb.ccipocr3.MessagesByTokenIDRequest.TokensEntryR\x06tokens\x1ae\n" + + "\vTokensEntry\x12\x10\n" + + "\x03key\x18\x01 \x01(\tR\x03key\x12@\n" + + "\x05value\x18\x02 \x01(\v2*.loop.internal.pb.ccipocr3.RampTokenAmountR\x05value:\x028\x01\"\xb8\x01\n" + + "\x19MessagesByTokenIDResponse\x12^\n" + + "\bmessages\x18\x01 \x03(\v2B.loop.internal.pb.ccipocr3.MessagesByTokenIDResponse.MessagesEntryR\bmessages\x1a;\n" + + "\rMessagesEntry\x12\x10\n" + + "\x03key\x18\x01 \x01(\tR\x03key\x12\x14\n" + + "\x05value\x18\x02 \x01(\fR\x05value:\x028\x01\"\xf7\x01\n" + + "\x17GetFeedPricesUSDRequest\x12\x16\n" + + "\x06tokens\x18\x01 \x03(\tR\x06tokens\x12`\n" + + "\n" + + "token_info\x18\x02 \x03(\v2A.loop.internal.pb.ccipocr3.GetFeedPricesUSDRequest.TokenInfoEntryR\ttokenInfo\x1ab\n" + + "\x0eTokenInfoEntry\x12\x10\n" + + "\x03key\x18\x01 \x01(\tR\x03key\x12:\n" + + "\x05value\x18\x02 \x01(\v2$.loop.internal.pb.ccipocr3.TokenInfoR\x05value:\x028\x01\"\xd1\x01\n" + + "\x18GetFeedPricesUSDResponse\x12W\n" + + "\x06prices\x18\x01 \x03(\v2?.loop.internal.pb.ccipocr3.GetFeedPricesUSDResponse.PricesEntryR\x06prices\x1a\\\n" + + "\vPricesEntry\x12\x10\n" + + "\x03key\x18\x01 \x01(\tR\x03key\x127\n" + + "\x05value\x18\x02 \x01(\v2!.loop.internal.pb.ccipocr3.BigIntR\x05value:\x028\x01\"`\n" + + "\x1fGetFeeQuoterTokenUpdatesRequest\x12\x16\n" + + "\x06tokens\x18\x01 \x03(\tR\x06tokens\x12%\n" + + "\x0echain_selector\x18\x02 \x01(\x04R\rchainSelector\"\x86\x02\n" + + " GetFeeQuoterTokenUpdatesResponse\x12r\n" + + "\rtoken_updates\x18\x01 \x03(\v2M.loop.internal.pb.ccipocr3.GetFeeQuoterTokenUpdatesResponse.TokenUpdatesEntryR\ftokenUpdates\x1an\n" + + "\x11TokenUpdatesEntry\x12\x10\n" + + "\x03key\x18\x01 \x01(\tR\x03key\x12C\n" + + "\x05value\x18\x02 \x01(\v2-.loop.internal.pb.ccipocr3.TimestampedUnixBigR\x05value:\x028\x01\"=\n" + + "\x0eMessageTokenID\x12\x15\n" + + "\x06seq_nr\x18\x01 \x01(\x04R\x05seqNr\x12\x14\n" + + "\x05index\x18\x02 \x01(\x05R\x05index\"\x9e\x01\n" + + "\tTokenInfo\x12-\n" + + "\x12aggregator_address\x18\x01 \x01(\tR\x11aggregatorAddress\x12F\n" + + "\rdeviation_ppb\x18\x02 \x01(\v2!.loop.internal.pb.ccipocr3.BigIntR\fdeviationPpb\x12\x1a\n" + + "\bdecimals\x18\x03 \x01(\rR\bdecimals2\xf6\x11\n" + "\rChainAccessor\x12\x81\x01\n" + "\x12GetContractAddress\x124.loop.internal.pb.ccipocr3.GetContractAddressRequest\x1a5.loop.internal.pb.ccipocr3.GetContractAddressResponse\x12\x84\x01\n" + "\x13GetAllConfigsLegacy\x125.loop.internal.pb.ccipocr3.GetAllConfigsLegacyRequest\x1a6.loop.internal.pb.ccipocr3.GetAllConfigsLegacyResponse\x12i\n" + @@ -3398,7 +3848,10 @@ const file_chainaccessor_proto_rawDesc = "" + "\x0fLatestMessageTo\x121.loop.internal.pb.ccipocr3.LatestMessageToRequest\x1a2.loop.internal.pb.ccipocr3.LatestMessageToResponse\x12\xa2\x01\n" + "\x1dGetExpectedNextSequenceNumber\x12?.loop.internal.pb.ccipocr3.GetExpectedNextSequenceNumberRequest\x1a@.loop.internal.pb.ccipocr3.GetExpectedNextSequenceNumberResponse\x12{\n" + "\x10GetTokenPriceUSD\x122.loop.internal.pb.ccipocr3.GetTokenPriceUSDRequest\x1a3.loop.internal.pb.ccipocr3.GetTokenPriceUSDResponse\x12\x9c\x01\n" + - "\x1bGetFeeQuoterDestChainConfig\x12=.loop.internal.pb.ccipocr3.GetFeeQuoterDestChainConfigRequest\x1a>.loop.internal.pb.ccipocr3.GetFeeQuoterDestChainConfigResponseBWZUgithub.com/smartcontractkit/chainlink-common/pkg/loop/internal/pb/ccipocr3;ccipocr3pbb\x06proto3" + "\x1bGetFeeQuoterDestChainConfig\x12=.loop.internal.pb.ccipocr3.GetFeeQuoterDestChainConfigRequest\x1a>.loop.internal.pb.ccipocr3.GetFeeQuoterDestChainConfigResponse\x12~\n" + + "\x11MessagesByTokenID\x123.loop.internal.pb.ccipocr3.MessagesByTokenIDRequest\x1a4.loop.internal.pb.ccipocr3.MessagesByTokenIDResponse\x12{\n" + + "\x10GetFeedPricesUSD\x122.loop.internal.pb.ccipocr3.GetFeedPricesUSDRequest\x1a3.loop.internal.pb.ccipocr3.GetFeedPricesUSDResponse\x12\x93\x01\n" + + "\x18GetFeeQuoterTokenUpdates\x12:.loop.internal.pb.ccipocr3.GetFeeQuoterTokenUpdatesRequest\x1a;.loop.internal.pb.ccipocr3.GetFeeQuoterTokenUpdatesResponseBWZUgithub.com/smartcontractkit/chainlink-common/pkg/loop/internal/pb/ccipocr3;ccipocr3pbb\x06proto3" var ( file_chainaccessor_proto_rawDescOnce sync.Once @@ -3412,7 +3865,7 @@ func file_chainaccessor_proto_rawDescGZIP() []byte { return file_chainaccessor_proto_rawDescData } -var file_chainaccessor_proto_msgTypes = make([]protoimpl.MessageInfo, 67) +var file_chainaccessor_proto_msgTypes = make([]protoimpl.MessageInfo, 80) var file_chainaccessor_proto_goTypes = []any{ (*GetContractAddressRequest)(nil), // 0: loop.internal.pb.ccipocr3.GetContractAddressRequest (*GetContractAddressResponse)(nil), // 1: loop.internal.pb.ccipocr3.GetContractAddressResponse @@ -3472,47 +3925,61 @@ var file_chainaccessor_proto_goTypes = []any{ (*CurseInfo)(nil), // 55: loop.internal.pb.ccipocr3.CurseInfo (*SourceChainConfig)(nil), // 56: loop.internal.pb.ccipocr3.SourceChainConfig (*FeeQuoterDestChainConfig)(nil), // 57: loop.internal.pb.ccipocr3.FeeQuoterDestChainConfig - nil, // 58: loop.internal.pb.ccipocr3.GetAllConfigsLegacyResponse.SourceChainConfigsEntry - nil, // 59: loop.internal.pb.ccipocr3.ExecutedMessagesRequest.RangesEntry - nil, // 60: loop.internal.pb.ccipocr3.ExecutedMessagesResponse.ExecutedMessagesEntry - nil, // 61: loop.internal.pb.ccipocr3.NextSeqNumResponse.NextSeqNumsEntry - nil, // 62: loop.internal.pb.ccipocr3.NoncesRequest.AddressesEntry - nil, // 63: loop.internal.pb.ccipocr3.NoncesResponse.NoncesEntry - nil, // 64: loop.internal.pb.ccipocr3.GetChainFeePriceUpdateResponse.FeePriceUpdatesEntry - nil, // 65: loop.internal.pb.ccipocr3.NonceMap.NoncesEntry - nil, // 66: loop.internal.pb.ccipocr3.CurseInfo.CursedSourceChainsEntry - (*timestamppb.Timestamp)(nil), // 67: google.protobuf.Timestamp - (*SeqNumRange)(nil), // 68: loop.internal.pb.ccipocr3.SeqNumRange - (*Message)(nil), // 69: loop.internal.pb.ccipocr3.Message - (*BigInt)(nil), // 70: loop.internal.pb.ccipocr3.BigInt - (*CommitPluginReport)(nil), // 71: loop.internal.pb.ccipocr3.CommitPluginReport - (*emptypb.Empty)(nil), // 72: google.protobuf.Empty + (*MessagesByTokenIDRequest)(nil), // 58: loop.internal.pb.ccipocr3.MessagesByTokenIDRequest + (*MessagesByTokenIDResponse)(nil), // 59: loop.internal.pb.ccipocr3.MessagesByTokenIDResponse + (*GetFeedPricesUSDRequest)(nil), // 60: loop.internal.pb.ccipocr3.GetFeedPricesUSDRequest + (*GetFeedPricesUSDResponse)(nil), // 61: loop.internal.pb.ccipocr3.GetFeedPricesUSDResponse + (*GetFeeQuoterTokenUpdatesRequest)(nil), // 62: loop.internal.pb.ccipocr3.GetFeeQuoterTokenUpdatesRequest + (*GetFeeQuoterTokenUpdatesResponse)(nil), // 63: loop.internal.pb.ccipocr3.GetFeeQuoterTokenUpdatesResponse + (*MessageTokenID)(nil), // 64: loop.internal.pb.ccipocr3.MessageTokenID + (*TokenInfo)(nil), // 65: loop.internal.pb.ccipocr3.TokenInfo + nil, // 66: loop.internal.pb.ccipocr3.GetAllConfigsLegacyResponse.SourceChainConfigsEntry + nil, // 67: loop.internal.pb.ccipocr3.ExecutedMessagesRequest.RangesEntry + nil, // 68: loop.internal.pb.ccipocr3.ExecutedMessagesResponse.ExecutedMessagesEntry + nil, // 69: loop.internal.pb.ccipocr3.NextSeqNumResponse.NextSeqNumsEntry + nil, // 70: loop.internal.pb.ccipocr3.NoncesRequest.AddressesEntry + nil, // 71: loop.internal.pb.ccipocr3.NoncesResponse.NoncesEntry + nil, // 72: loop.internal.pb.ccipocr3.GetChainFeePriceUpdateResponse.FeePriceUpdatesEntry + nil, // 73: loop.internal.pb.ccipocr3.NonceMap.NoncesEntry + nil, // 74: loop.internal.pb.ccipocr3.CurseInfo.CursedSourceChainsEntry + nil, // 75: loop.internal.pb.ccipocr3.MessagesByTokenIDRequest.TokensEntry + nil, // 76: loop.internal.pb.ccipocr3.MessagesByTokenIDResponse.MessagesEntry + nil, // 77: loop.internal.pb.ccipocr3.GetFeedPricesUSDRequest.TokenInfoEntry + nil, // 78: loop.internal.pb.ccipocr3.GetFeedPricesUSDResponse.PricesEntry + nil, // 79: loop.internal.pb.ccipocr3.GetFeeQuoterTokenUpdatesResponse.TokenUpdatesEntry + (*timestamppb.Timestamp)(nil), // 80: google.protobuf.Timestamp + (*SeqNumRange)(nil), // 81: loop.internal.pb.ccipocr3.SeqNumRange + (*Message)(nil), // 82: loop.internal.pb.ccipocr3.Message + (*BigInt)(nil), // 83: loop.internal.pb.ccipocr3.BigInt + (*CommitPluginReport)(nil), // 84: loop.internal.pb.ccipocr3.CommitPluginReport + (*RampTokenAmount)(nil), // 85: loop.internal.pb.ccipocr3.RampTokenAmount + (*emptypb.Empty)(nil), // 86: google.protobuf.Empty } var file_chainaccessor_proto_depIdxs = []int32{ 54, // 0: loop.internal.pb.ccipocr3.GetAllConfigsLegacyResponse.snapshot:type_name -> loop.internal.pb.ccipocr3.ChainConfigSnapshot - 58, // 1: loop.internal.pb.ccipocr3.GetAllConfigsLegacyResponse.source_chain_configs:type_name -> loop.internal.pb.ccipocr3.GetAllConfigsLegacyResponse.SourceChainConfigsEntry + 66, // 1: loop.internal.pb.ccipocr3.GetAllConfigsLegacyResponse.source_chain_configs:type_name -> loop.internal.pb.ccipocr3.GetAllConfigsLegacyResponse.SourceChainConfigsEntry 27, // 2: loop.internal.pb.ccipocr3.GetChainFeeComponentsResponse.fee_components:type_name -> loop.internal.pb.ccipocr3.ChainFeeComponents - 67, // 3: loop.internal.pb.ccipocr3.CommitReportsGTETimestampRequest.timestamp:type_name -> google.protobuf.Timestamp + 80, // 3: loop.internal.pb.ccipocr3.CommitReportsGTETimestampRequest.timestamp:type_name -> google.protobuf.Timestamp 28, // 4: loop.internal.pb.ccipocr3.CommitReportsGTETimestampResponse.reports:type_name -> loop.internal.pb.ccipocr3.CommitPluginReportWithMeta - 59, // 5: loop.internal.pb.ccipocr3.ExecutedMessagesRequest.ranges:type_name -> loop.internal.pb.ccipocr3.ExecutedMessagesRequest.RangesEntry - 60, // 6: loop.internal.pb.ccipocr3.ExecutedMessagesResponse.executed_messages:type_name -> loop.internal.pb.ccipocr3.ExecutedMessagesResponse.ExecutedMessagesEntry - 61, // 7: loop.internal.pb.ccipocr3.NextSeqNumResponse.next_seq_nums:type_name -> loop.internal.pb.ccipocr3.NextSeqNumResponse.NextSeqNumsEntry - 62, // 8: loop.internal.pb.ccipocr3.NoncesRequest.addresses:type_name -> loop.internal.pb.ccipocr3.NoncesRequest.AddressesEntry - 63, // 9: loop.internal.pb.ccipocr3.NoncesResponse.nonces:type_name -> loop.internal.pb.ccipocr3.NoncesResponse.NoncesEntry - 64, // 10: loop.internal.pb.ccipocr3.GetChainFeePriceUpdateResponse.fee_price_updates:type_name -> loop.internal.pb.ccipocr3.GetChainFeePriceUpdateResponse.FeePriceUpdatesEntry - 68, // 11: loop.internal.pb.ccipocr3.MsgsBetweenSeqNumsRequest.seq_num_range:type_name -> loop.internal.pb.ccipocr3.SeqNumRange - 69, // 12: loop.internal.pb.ccipocr3.MsgsBetweenSeqNumsResponse.messages:type_name -> loop.internal.pb.ccipocr3.Message + 67, // 5: loop.internal.pb.ccipocr3.ExecutedMessagesRequest.ranges:type_name -> loop.internal.pb.ccipocr3.ExecutedMessagesRequest.RangesEntry + 68, // 6: loop.internal.pb.ccipocr3.ExecutedMessagesResponse.executed_messages:type_name -> loop.internal.pb.ccipocr3.ExecutedMessagesResponse.ExecutedMessagesEntry + 69, // 7: loop.internal.pb.ccipocr3.NextSeqNumResponse.next_seq_nums:type_name -> loop.internal.pb.ccipocr3.NextSeqNumResponse.NextSeqNumsEntry + 70, // 8: loop.internal.pb.ccipocr3.NoncesRequest.addresses:type_name -> loop.internal.pb.ccipocr3.NoncesRequest.AddressesEntry + 71, // 9: loop.internal.pb.ccipocr3.NoncesResponse.nonces:type_name -> loop.internal.pb.ccipocr3.NoncesResponse.NoncesEntry + 72, // 10: loop.internal.pb.ccipocr3.GetChainFeePriceUpdateResponse.fee_price_updates:type_name -> loop.internal.pb.ccipocr3.GetChainFeePriceUpdateResponse.FeePriceUpdatesEntry + 81, // 11: loop.internal.pb.ccipocr3.MsgsBetweenSeqNumsRequest.seq_num_range:type_name -> loop.internal.pb.ccipocr3.SeqNumRange + 82, // 12: loop.internal.pb.ccipocr3.MsgsBetweenSeqNumsResponse.messages:type_name -> loop.internal.pb.ccipocr3.Message 30, // 13: loop.internal.pb.ccipocr3.GetTokenPriceUSDResponse.price:type_name -> loop.internal.pb.ccipocr3.TimestampedUnixBig 57, // 14: loop.internal.pb.ccipocr3.GetFeeQuoterDestChainConfigResponse.config:type_name -> loop.internal.pb.ccipocr3.FeeQuoterDestChainConfig - 70, // 15: loop.internal.pb.ccipocr3.ChainFeeComponents.execution_fee:type_name -> loop.internal.pb.ccipocr3.BigInt - 70, // 16: loop.internal.pb.ccipocr3.ChainFeeComponents.data_availability_fee:type_name -> loop.internal.pb.ccipocr3.BigInt - 71, // 17: loop.internal.pb.ccipocr3.CommitPluginReportWithMeta.report:type_name -> loop.internal.pb.ccipocr3.CommitPluginReport - 67, // 18: loop.internal.pb.ccipocr3.CommitPluginReportWithMeta.timestamp:type_name -> google.protobuf.Timestamp - 67, // 19: loop.internal.pb.ccipocr3.TimestampedBig.timestamp:type_name -> google.protobuf.Timestamp - 70, // 20: loop.internal.pb.ccipocr3.TimestampedBig.value:type_name -> loop.internal.pb.ccipocr3.BigInt - 70, // 21: loop.internal.pb.ccipocr3.TimestampedUnixBig.value:type_name -> loop.internal.pb.ccipocr3.BigInt - 68, // 22: loop.internal.pb.ccipocr3.SequenceNumberRangeList.ranges:type_name -> loop.internal.pb.ccipocr3.SeqNumRange - 65, // 23: loop.internal.pb.ccipocr3.NonceMap.nonces:type_name -> loop.internal.pb.ccipocr3.NonceMap.NoncesEntry + 83, // 15: loop.internal.pb.ccipocr3.ChainFeeComponents.execution_fee:type_name -> loop.internal.pb.ccipocr3.BigInt + 83, // 16: loop.internal.pb.ccipocr3.ChainFeeComponents.data_availability_fee:type_name -> loop.internal.pb.ccipocr3.BigInt + 84, // 17: loop.internal.pb.ccipocr3.CommitPluginReportWithMeta.report:type_name -> loop.internal.pb.ccipocr3.CommitPluginReport + 80, // 18: loop.internal.pb.ccipocr3.CommitPluginReportWithMeta.timestamp:type_name -> google.protobuf.Timestamp + 80, // 19: loop.internal.pb.ccipocr3.TimestampedBig.timestamp:type_name -> google.protobuf.Timestamp + 83, // 20: loop.internal.pb.ccipocr3.TimestampedBig.value:type_name -> loop.internal.pb.ccipocr3.BigInt + 83, // 21: loop.internal.pb.ccipocr3.TimestampedUnixBig.value:type_name -> loop.internal.pb.ccipocr3.BigInt + 81, // 22: loop.internal.pb.ccipocr3.SequenceNumberRangeList.ranges:type_name -> loop.internal.pb.ccipocr3.SeqNumRange + 73, // 23: loop.internal.pb.ccipocr3.NonceMap.nonces:type_name -> loop.internal.pb.ccipocr3.NonceMap.NoncesEntry 36, // 24: loop.internal.pb.ccipocr3.OfframpConfig.commit_latest_ocr_config:type_name -> loop.internal.pb.ccipocr3.OCRConfigResponse 36, // 25: loop.internal.pb.ccipocr3.OfframpConfig.exec_latest_ocr_config:type_name -> loop.internal.pb.ccipocr3.OCRConfigResponse 39, // 26: loop.internal.pb.ccipocr3.OfframpConfig.static_config:type_name -> loop.internal.pb.ccipocr3.OffRampStaticChainConfig @@ -3524,7 +3991,7 @@ var file_chainaccessor_proto_depIdxs = []int32{ 45, // 32: loop.internal.pb.ccipocr3.VersionedConfig.config:type_name -> loop.internal.pb.ccipocr3.RMNConfig 46, // 33: loop.internal.pb.ccipocr3.RMNConfig.signers:type_name -> loop.internal.pb.ccipocr3.SignerInfo 48, // 34: loop.internal.pb.ccipocr3.FeeQuoterConfigStruct.static_config:type_name -> loop.internal.pb.ccipocr3.FeeQuoterStaticConfigStruct - 70, // 35: loop.internal.pb.ccipocr3.FeeQuoterStaticConfigStruct.max_fee_juels_per_msg:type_name -> loop.internal.pb.ccipocr3.BigInt + 83, // 35: loop.internal.pb.ccipocr3.FeeQuoterStaticConfigStruct.max_fee_juels_per_msg:type_name -> loop.internal.pb.ccipocr3.BigInt 50, // 36: loop.internal.pb.ccipocr3.OnRampConfigStruct.dynamic_config:type_name -> loop.internal.pb.ccipocr3.GetOnRampDynamicConfigResponse 52, // 37: loop.internal.pb.ccipocr3.OnRampConfigStruct.dest_chain_config:type_name -> loop.internal.pb.ccipocr3.OnRampDestChainConfig 51, // 38: loop.internal.pb.ccipocr3.GetOnRampDynamicConfigResponse.dynamic_config:type_name -> loop.internal.pb.ccipocr3.OnRampDynamicConfig @@ -3535,48 +4002,64 @@ var file_chainaccessor_proto_depIdxs = []int32{ 49, // 43: loop.internal.pb.ccipocr3.ChainConfigSnapshot.on_ramp:type_name -> loop.internal.pb.ccipocr3.OnRampConfigStruct 53, // 44: loop.internal.pb.ccipocr3.ChainConfigSnapshot.router:type_name -> loop.internal.pb.ccipocr3.RouterConfigStruct 55, // 45: loop.internal.pb.ccipocr3.ChainConfigSnapshot.curse_info:type_name -> loop.internal.pb.ccipocr3.CurseInfo - 66, // 46: loop.internal.pb.ccipocr3.CurseInfo.cursed_source_chains:type_name -> loop.internal.pb.ccipocr3.CurseInfo.CursedSourceChainsEntry - 56, // 47: loop.internal.pb.ccipocr3.GetAllConfigsLegacyResponse.SourceChainConfigsEntry.value:type_name -> loop.internal.pb.ccipocr3.SourceChainConfig - 31, // 48: loop.internal.pb.ccipocr3.ExecutedMessagesRequest.RangesEntry.value:type_name -> loop.internal.pb.ccipocr3.SequenceNumberRangeList - 32, // 49: loop.internal.pb.ccipocr3.ExecutedMessagesResponse.ExecutedMessagesEntry.value:type_name -> loop.internal.pb.ccipocr3.SequenceNumberList - 33, // 50: loop.internal.pb.ccipocr3.NoncesRequest.AddressesEntry.value:type_name -> loop.internal.pb.ccipocr3.UnknownEncodedAddressList - 34, // 51: loop.internal.pb.ccipocr3.NoncesResponse.NoncesEntry.value:type_name -> loop.internal.pb.ccipocr3.NonceMap - 29, // 52: loop.internal.pb.ccipocr3.GetChainFeePriceUpdateResponse.FeePriceUpdatesEntry.value:type_name -> loop.internal.pb.ccipocr3.TimestampedBig - 0, // 53: loop.internal.pb.ccipocr3.ChainAccessor.GetContractAddress:input_type -> loop.internal.pb.ccipocr3.GetContractAddressRequest - 2, // 54: loop.internal.pb.ccipocr3.ChainAccessor.GetAllConfigsLegacy:input_type -> loop.internal.pb.ccipocr3.GetAllConfigsLegacyRequest - 72, // 55: loop.internal.pb.ccipocr3.ChainAccessor.GetChainFeeComponents:input_type -> google.protobuf.Empty - 5, // 56: loop.internal.pb.ccipocr3.ChainAccessor.Sync:input_type -> loop.internal.pb.ccipocr3.SyncRequest - 6, // 57: loop.internal.pb.ccipocr3.ChainAccessor.CommitReportsGTETimestamp:input_type -> loop.internal.pb.ccipocr3.CommitReportsGTETimestampRequest - 8, // 58: loop.internal.pb.ccipocr3.ChainAccessor.ExecutedMessages:input_type -> loop.internal.pb.ccipocr3.ExecutedMessagesRequest - 10, // 59: loop.internal.pb.ccipocr3.ChainAccessor.NextSeqNum:input_type -> loop.internal.pb.ccipocr3.NextSeqNumRequest - 12, // 60: loop.internal.pb.ccipocr3.ChainAccessor.Nonces:input_type -> loop.internal.pb.ccipocr3.NoncesRequest - 14, // 61: loop.internal.pb.ccipocr3.ChainAccessor.GetChainFeePriceUpdate:input_type -> loop.internal.pb.ccipocr3.GetChainFeePriceUpdateRequest - 72, // 62: loop.internal.pb.ccipocr3.ChainAccessor.GetLatestPriceSeqNr:input_type -> google.protobuf.Empty - 17, // 63: loop.internal.pb.ccipocr3.ChainAccessor.MsgsBetweenSeqNums:input_type -> loop.internal.pb.ccipocr3.MsgsBetweenSeqNumsRequest - 19, // 64: loop.internal.pb.ccipocr3.ChainAccessor.LatestMessageTo:input_type -> loop.internal.pb.ccipocr3.LatestMessageToRequest - 21, // 65: loop.internal.pb.ccipocr3.ChainAccessor.GetExpectedNextSequenceNumber:input_type -> loop.internal.pb.ccipocr3.GetExpectedNextSequenceNumberRequest - 23, // 66: loop.internal.pb.ccipocr3.ChainAccessor.GetTokenPriceUSD:input_type -> loop.internal.pb.ccipocr3.GetTokenPriceUSDRequest - 25, // 67: loop.internal.pb.ccipocr3.ChainAccessor.GetFeeQuoterDestChainConfig:input_type -> loop.internal.pb.ccipocr3.GetFeeQuoterDestChainConfigRequest - 1, // 68: loop.internal.pb.ccipocr3.ChainAccessor.GetContractAddress:output_type -> loop.internal.pb.ccipocr3.GetContractAddressResponse - 3, // 69: loop.internal.pb.ccipocr3.ChainAccessor.GetAllConfigsLegacy:output_type -> loop.internal.pb.ccipocr3.GetAllConfigsLegacyResponse - 4, // 70: loop.internal.pb.ccipocr3.ChainAccessor.GetChainFeeComponents:output_type -> loop.internal.pb.ccipocr3.GetChainFeeComponentsResponse - 72, // 71: loop.internal.pb.ccipocr3.ChainAccessor.Sync:output_type -> google.protobuf.Empty - 7, // 72: loop.internal.pb.ccipocr3.ChainAccessor.CommitReportsGTETimestamp:output_type -> loop.internal.pb.ccipocr3.CommitReportsGTETimestampResponse - 9, // 73: loop.internal.pb.ccipocr3.ChainAccessor.ExecutedMessages:output_type -> loop.internal.pb.ccipocr3.ExecutedMessagesResponse - 11, // 74: loop.internal.pb.ccipocr3.ChainAccessor.NextSeqNum:output_type -> loop.internal.pb.ccipocr3.NextSeqNumResponse - 13, // 75: loop.internal.pb.ccipocr3.ChainAccessor.Nonces:output_type -> loop.internal.pb.ccipocr3.NoncesResponse - 15, // 76: loop.internal.pb.ccipocr3.ChainAccessor.GetChainFeePriceUpdate:output_type -> loop.internal.pb.ccipocr3.GetChainFeePriceUpdateResponse - 16, // 77: loop.internal.pb.ccipocr3.ChainAccessor.GetLatestPriceSeqNr:output_type -> loop.internal.pb.ccipocr3.GetLatestPriceSeqNrResponse - 18, // 78: loop.internal.pb.ccipocr3.ChainAccessor.MsgsBetweenSeqNums:output_type -> loop.internal.pb.ccipocr3.MsgsBetweenSeqNumsResponse - 20, // 79: loop.internal.pb.ccipocr3.ChainAccessor.LatestMessageTo:output_type -> loop.internal.pb.ccipocr3.LatestMessageToResponse - 22, // 80: loop.internal.pb.ccipocr3.ChainAccessor.GetExpectedNextSequenceNumber:output_type -> loop.internal.pb.ccipocr3.GetExpectedNextSequenceNumberResponse - 24, // 81: loop.internal.pb.ccipocr3.ChainAccessor.GetTokenPriceUSD:output_type -> loop.internal.pb.ccipocr3.GetTokenPriceUSDResponse - 26, // 82: loop.internal.pb.ccipocr3.ChainAccessor.GetFeeQuoterDestChainConfig:output_type -> loop.internal.pb.ccipocr3.GetFeeQuoterDestChainConfigResponse - 68, // [68:83] is the sub-list for method output_type - 53, // [53:68] is the sub-list for method input_type - 53, // [53:53] is the sub-list for extension type_name - 53, // [53:53] is the sub-list for extension extendee - 0, // [0:53] is the sub-list for field type_name + 74, // 46: loop.internal.pb.ccipocr3.CurseInfo.cursed_source_chains:type_name -> loop.internal.pb.ccipocr3.CurseInfo.CursedSourceChainsEntry + 75, // 47: loop.internal.pb.ccipocr3.MessagesByTokenIDRequest.tokens:type_name -> loop.internal.pb.ccipocr3.MessagesByTokenIDRequest.TokensEntry + 76, // 48: loop.internal.pb.ccipocr3.MessagesByTokenIDResponse.messages:type_name -> loop.internal.pb.ccipocr3.MessagesByTokenIDResponse.MessagesEntry + 77, // 49: loop.internal.pb.ccipocr3.GetFeedPricesUSDRequest.token_info:type_name -> loop.internal.pb.ccipocr3.GetFeedPricesUSDRequest.TokenInfoEntry + 78, // 50: loop.internal.pb.ccipocr3.GetFeedPricesUSDResponse.prices:type_name -> loop.internal.pb.ccipocr3.GetFeedPricesUSDResponse.PricesEntry + 79, // 51: loop.internal.pb.ccipocr3.GetFeeQuoterTokenUpdatesResponse.token_updates:type_name -> loop.internal.pb.ccipocr3.GetFeeQuoterTokenUpdatesResponse.TokenUpdatesEntry + 83, // 52: loop.internal.pb.ccipocr3.TokenInfo.deviation_ppb:type_name -> loop.internal.pb.ccipocr3.BigInt + 56, // 53: loop.internal.pb.ccipocr3.GetAllConfigsLegacyResponse.SourceChainConfigsEntry.value:type_name -> loop.internal.pb.ccipocr3.SourceChainConfig + 31, // 54: loop.internal.pb.ccipocr3.ExecutedMessagesRequest.RangesEntry.value:type_name -> loop.internal.pb.ccipocr3.SequenceNumberRangeList + 32, // 55: loop.internal.pb.ccipocr3.ExecutedMessagesResponse.ExecutedMessagesEntry.value:type_name -> loop.internal.pb.ccipocr3.SequenceNumberList + 33, // 56: loop.internal.pb.ccipocr3.NoncesRequest.AddressesEntry.value:type_name -> loop.internal.pb.ccipocr3.UnknownEncodedAddressList + 34, // 57: loop.internal.pb.ccipocr3.NoncesResponse.NoncesEntry.value:type_name -> loop.internal.pb.ccipocr3.NonceMap + 30, // 58: loop.internal.pb.ccipocr3.GetChainFeePriceUpdateResponse.FeePriceUpdatesEntry.value:type_name -> loop.internal.pb.ccipocr3.TimestampedUnixBig + 85, // 59: loop.internal.pb.ccipocr3.MessagesByTokenIDRequest.TokensEntry.value:type_name -> loop.internal.pb.ccipocr3.RampTokenAmount + 65, // 60: loop.internal.pb.ccipocr3.GetFeedPricesUSDRequest.TokenInfoEntry.value:type_name -> loop.internal.pb.ccipocr3.TokenInfo + 83, // 61: loop.internal.pb.ccipocr3.GetFeedPricesUSDResponse.PricesEntry.value:type_name -> loop.internal.pb.ccipocr3.BigInt + 30, // 62: loop.internal.pb.ccipocr3.GetFeeQuoterTokenUpdatesResponse.TokenUpdatesEntry.value:type_name -> loop.internal.pb.ccipocr3.TimestampedUnixBig + 0, // 63: loop.internal.pb.ccipocr3.ChainAccessor.GetContractAddress:input_type -> loop.internal.pb.ccipocr3.GetContractAddressRequest + 2, // 64: loop.internal.pb.ccipocr3.ChainAccessor.GetAllConfigsLegacy:input_type -> loop.internal.pb.ccipocr3.GetAllConfigsLegacyRequest + 86, // 65: loop.internal.pb.ccipocr3.ChainAccessor.GetChainFeeComponents:input_type -> google.protobuf.Empty + 5, // 66: loop.internal.pb.ccipocr3.ChainAccessor.Sync:input_type -> loop.internal.pb.ccipocr3.SyncRequest + 6, // 67: loop.internal.pb.ccipocr3.ChainAccessor.CommitReportsGTETimestamp:input_type -> loop.internal.pb.ccipocr3.CommitReportsGTETimestampRequest + 8, // 68: loop.internal.pb.ccipocr3.ChainAccessor.ExecutedMessages:input_type -> loop.internal.pb.ccipocr3.ExecutedMessagesRequest + 10, // 69: loop.internal.pb.ccipocr3.ChainAccessor.NextSeqNum:input_type -> loop.internal.pb.ccipocr3.NextSeqNumRequest + 12, // 70: loop.internal.pb.ccipocr3.ChainAccessor.Nonces:input_type -> loop.internal.pb.ccipocr3.NoncesRequest + 14, // 71: loop.internal.pb.ccipocr3.ChainAccessor.GetChainFeePriceUpdate:input_type -> loop.internal.pb.ccipocr3.GetChainFeePriceUpdateRequest + 86, // 72: loop.internal.pb.ccipocr3.ChainAccessor.GetLatestPriceSeqNr:input_type -> google.protobuf.Empty + 17, // 73: loop.internal.pb.ccipocr3.ChainAccessor.MsgsBetweenSeqNums:input_type -> loop.internal.pb.ccipocr3.MsgsBetweenSeqNumsRequest + 19, // 74: loop.internal.pb.ccipocr3.ChainAccessor.LatestMessageTo:input_type -> loop.internal.pb.ccipocr3.LatestMessageToRequest + 21, // 75: loop.internal.pb.ccipocr3.ChainAccessor.GetExpectedNextSequenceNumber:input_type -> loop.internal.pb.ccipocr3.GetExpectedNextSequenceNumberRequest + 23, // 76: loop.internal.pb.ccipocr3.ChainAccessor.GetTokenPriceUSD:input_type -> loop.internal.pb.ccipocr3.GetTokenPriceUSDRequest + 25, // 77: loop.internal.pb.ccipocr3.ChainAccessor.GetFeeQuoterDestChainConfig:input_type -> loop.internal.pb.ccipocr3.GetFeeQuoterDestChainConfigRequest + 58, // 78: loop.internal.pb.ccipocr3.ChainAccessor.MessagesByTokenID:input_type -> loop.internal.pb.ccipocr3.MessagesByTokenIDRequest + 60, // 79: loop.internal.pb.ccipocr3.ChainAccessor.GetFeedPricesUSD:input_type -> loop.internal.pb.ccipocr3.GetFeedPricesUSDRequest + 62, // 80: loop.internal.pb.ccipocr3.ChainAccessor.GetFeeQuoterTokenUpdates:input_type -> loop.internal.pb.ccipocr3.GetFeeQuoterTokenUpdatesRequest + 1, // 81: loop.internal.pb.ccipocr3.ChainAccessor.GetContractAddress:output_type -> loop.internal.pb.ccipocr3.GetContractAddressResponse + 3, // 82: loop.internal.pb.ccipocr3.ChainAccessor.GetAllConfigsLegacy:output_type -> loop.internal.pb.ccipocr3.GetAllConfigsLegacyResponse + 4, // 83: loop.internal.pb.ccipocr3.ChainAccessor.GetChainFeeComponents:output_type -> loop.internal.pb.ccipocr3.GetChainFeeComponentsResponse + 86, // 84: loop.internal.pb.ccipocr3.ChainAccessor.Sync:output_type -> google.protobuf.Empty + 7, // 85: loop.internal.pb.ccipocr3.ChainAccessor.CommitReportsGTETimestamp:output_type -> loop.internal.pb.ccipocr3.CommitReportsGTETimestampResponse + 9, // 86: loop.internal.pb.ccipocr3.ChainAccessor.ExecutedMessages:output_type -> loop.internal.pb.ccipocr3.ExecutedMessagesResponse + 11, // 87: loop.internal.pb.ccipocr3.ChainAccessor.NextSeqNum:output_type -> loop.internal.pb.ccipocr3.NextSeqNumResponse + 13, // 88: loop.internal.pb.ccipocr3.ChainAccessor.Nonces:output_type -> loop.internal.pb.ccipocr3.NoncesResponse + 15, // 89: loop.internal.pb.ccipocr3.ChainAccessor.GetChainFeePriceUpdate:output_type -> loop.internal.pb.ccipocr3.GetChainFeePriceUpdateResponse + 16, // 90: loop.internal.pb.ccipocr3.ChainAccessor.GetLatestPriceSeqNr:output_type -> loop.internal.pb.ccipocr3.GetLatestPriceSeqNrResponse + 18, // 91: loop.internal.pb.ccipocr3.ChainAccessor.MsgsBetweenSeqNums:output_type -> loop.internal.pb.ccipocr3.MsgsBetweenSeqNumsResponse + 20, // 92: loop.internal.pb.ccipocr3.ChainAccessor.LatestMessageTo:output_type -> loop.internal.pb.ccipocr3.LatestMessageToResponse + 22, // 93: loop.internal.pb.ccipocr3.ChainAccessor.GetExpectedNextSequenceNumber:output_type -> loop.internal.pb.ccipocr3.GetExpectedNextSequenceNumberResponse + 24, // 94: loop.internal.pb.ccipocr3.ChainAccessor.GetTokenPriceUSD:output_type -> loop.internal.pb.ccipocr3.GetTokenPriceUSDResponse + 26, // 95: loop.internal.pb.ccipocr3.ChainAccessor.GetFeeQuoterDestChainConfig:output_type -> loop.internal.pb.ccipocr3.GetFeeQuoterDestChainConfigResponse + 59, // 96: loop.internal.pb.ccipocr3.ChainAccessor.MessagesByTokenID:output_type -> loop.internal.pb.ccipocr3.MessagesByTokenIDResponse + 61, // 97: loop.internal.pb.ccipocr3.ChainAccessor.GetFeedPricesUSD:output_type -> loop.internal.pb.ccipocr3.GetFeedPricesUSDResponse + 63, // 98: loop.internal.pb.ccipocr3.ChainAccessor.GetFeeQuoterTokenUpdates:output_type -> loop.internal.pb.ccipocr3.GetFeeQuoterTokenUpdatesResponse + 81, // [81:99] is the sub-list for method output_type + 63, // [63:81] is the sub-list for method input_type + 63, // [63:63] is the sub-list for extension type_name + 63, // [63:63] is the sub-list for extension extendee + 0, // [0:63] is the sub-list for field type_name } func init() { file_chainaccessor_proto_init() } @@ -3591,7 +4074,7 @@ func file_chainaccessor_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: unsafe.Slice(unsafe.StringData(file_chainaccessor_proto_rawDesc), len(file_chainaccessor_proto_rawDesc)), NumEnums: 0, - NumMessages: 67, + NumMessages: 80, NumExtensions: 0, NumServices: 1, }, diff --git a/pkg/loop/internal/pb/ccipocr3/chainaccessor.proto b/pkg/loop/internal/pb/ccipocr3/chainaccessor.proto index 8b170ec5a..d9faef8e8 100644 --- a/pkg/loop/internal/pb/ccipocr3/chainaccessor.proto +++ b/pkg/loop/internal/pb/ccipocr3/chainaccessor.proto @@ -30,6 +30,13 @@ service ChainAccessor { rpc GetExpectedNextSequenceNumber(GetExpectedNextSequenceNumberRequest) returns (GetExpectedNextSequenceNumberResponse); rpc GetTokenPriceUSD(GetTokenPriceUSDRequest) returns (GetTokenPriceUSDResponse); rpc GetFeeQuoterDestChainConfig(GetFeeQuoterDestChainConfigRequest) returns (GetFeeQuoterDestChainConfigResponse); + + // USDCMessageReader methods + rpc MessagesByTokenID(MessagesByTokenIDRequest) returns (MessagesByTokenIDResponse); + + // PriceReader methods + rpc GetFeedPricesUSD(GetFeedPricesUSDRequest) returns (GetFeedPricesUSDResponse); + rpc GetFeeQuoterTokenUpdates(GetFeeQuoterTokenUpdatesRequest) returns (GetFeeQuoterTokenUpdatesResponse); } // AllAccessors request/response messages @@ -101,7 +108,7 @@ message GetChainFeePriceUpdateRequest { } message GetChainFeePriceUpdateResponse { - map fee_price_updates = 1; // key is chain selector + map fee_price_updates = 1; // key is chain selector } message GetLatestPriceSeqNrResponse { @@ -337,4 +344,46 @@ message FeeQuoterDestChainConfig { uint32 gas_price_staleness_threshold = 19; bool enforce_out_of_order = 15; bytes chain_family_selector = 16; // [4]byte in Go +} + +// USDCMessageReader request/response messages +message MessagesByTokenIDRequest { + uint64 source_chain_selector = 1; + uint64 dest_chain_selector = 2; + map tokens = 3; // key is MessageTokenID string representation +} + +message MessagesByTokenIDResponse { + map messages = 1; // key is MessageTokenID string representation, value is message bytes +} + +// PriceReader request/response messages +message GetFeedPricesUSDRequest { + repeated string tokens = 1; // UnknownEncodedAddress + map token_info = 2; // key is UnknownEncodedAddress +} + +message GetFeedPricesUSDResponse { + map prices = 1; // key is UnknownEncodedAddress, value is price +} + +message GetFeeQuoterTokenUpdatesRequest { + repeated string tokens = 1; // UnknownEncodedAddress + uint64 chain_selector = 2; +} + +message GetFeeQuoterTokenUpdatesResponse { + map token_updates = 1; // key is UnknownEncodedAddress +} + +// Helper message types +message MessageTokenID { + uint64 seq_nr = 1; + int32 index = 2; +} + +message TokenInfo { + string aggregator_address = 1; // UnknownEncodedAddress + BigInt deviation_ppb = 2; + uint32 decimals = 3; } \ No newline at end of file diff --git a/pkg/loop/internal/pb/ccipocr3/chainaccessor_grpc.pb.go b/pkg/loop/internal/pb/ccipocr3/chainaccessor_grpc.pb.go index 540ed4288..96d53631d 100644 --- a/pkg/loop/internal/pb/ccipocr3/chainaccessor_grpc.pb.go +++ b/pkg/loop/internal/pb/ccipocr3/chainaccessor_grpc.pb.go @@ -35,6 +35,9 @@ const ( ChainAccessor_GetExpectedNextSequenceNumber_FullMethodName = "/loop.internal.pb.ccipocr3.ChainAccessor/GetExpectedNextSequenceNumber" ChainAccessor_GetTokenPriceUSD_FullMethodName = "/loop.internal.pb.ccipocr3.ChainAccessor/GetTokenPriceUSD" ChainAccessor_GetFeeQuoterDestChainConfig_FullMethodName = "/loop.internal.pb.ccipocr3.ChainAccessor/GetFeeQuoterDestChainConfig" + ChainAccessor_MessagesByTokenID_FullMethodName = "/loop.internal.pb.ccipocr3.ChainAccessor/MessagesByTokenID" + ChainAccessor_GetFeedPricesUSD_FullMethodName = "/loop.internal.pb.ccipocr3.ChainAccessor/GetFeedPricesUSD" + ChainAccessor_GetFeeQuoterTokenUpdates_FullMethodName = "/loop.internal.pb.ccipocr3.ChainAccessor/GetFeeQuoterTokenUpdates" ) // ChainAccessorClient is the client API for ChainAccessor service. @@ -61,6 +64,11 @@ type ChainAccessorClient interface { GetExpectedNextSequenceNumber(ctx context.Context, in *GetExpectedNextSequenceNumberRequest, opts ...grpc.CallOption) (*GetExpectedNextSequenceNumberResponse, error) GetTokenPriceUSD(ctx context.Context, in *GetTokenPriceUSDRequest, opts ...grpc.CallOption) (*GetTokenPriceUSDResponse, error) GetFeeQuoterDestChainConfig(ctx context.Context, in *GetFeeQuoterDestChainConfigRequest, opts ...grpc.CallOption) (*GetFeeQuoterDestChainConfigResponse, error) + // USDCMessageReader methods + MessagesByTokenID(ctx context.Context, in *MessagesByTokenIDRequest, opts ...grpc.CallOption) (*MessagesByTokenIDResponse, error) + // PriceReader methods + GetFeedPricesUSD(ctx context.Context, in *GetFeedPricesUSDRequest, opts ...grpc.CallOption) (*GetFeedPricesUSDResponse, error) + GetFeeQuoterTokenUpdates(ctx context.Context, in *GetFeeQuoterTokenUpdatesRequest, opts ...grpc.CallOption) (*GetFeeQuoterTokenUpdatesResponse, error) } type chainAccessorClient struct { @@ -221,6 +229,36 @@ func (c *chainAccessorClient) GetFeeQuoterDestChainConfig(ctx context.Context, i return out, nil } +func (c *chainAccessorClient) MessagesByTokenID(ctx context.Context, in *MessagesByTokenIDRequest, opts ...grpc.CallOption) (*MessagesByTokenIDResponse, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(MessagesByTokenIDResponse) + err := c.cc.Invoke(ctx, ChainAccessor_MessagesByTokenID_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *chainAccessorClient) GetFeedPricesUSD(ctx context.Context, in *GetFeedPricesUSDRequest, opts ...grpc.CallOption) (*GetFeedPricesUSDResponse, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(GetFeedPricesUSDResponse) + err := c.cc.Invoke(ctx, ChainAccessor_GetFeedPricesUSD_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *chainAccessorClient) GetFeeQuoterTokenUpdates(ctx context.Context, in *GetFeeQuoterTokenUpdatesRequest, opts ...grpc.CallOption) (*GetFeeQuoterTokenUpdatesResponse, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(GetFeeQuoterTokenUpdatesResponse) + err := c.cc.Invoke(ctx, ChainAccessor_GetFeeQuoterTokenUpdates_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + // ChainAccessorServer is the server API for ChainAccessor service. // All implementations must embed UnimplementedChainAccessorServer // for forward compatibility. @@ -245,6 +283,11 @@ type ChainAccessorServer interface { GetExpectedNextSequenceNumber(context.Context, *GetExpectedNextSequenceNumberRequest) (*GetExpectedNextSequenceNumberResponse, error) GetTokenPriceUSD(context.Context, *GetTokenPriceUSDRequest) (*GetTokenPriceUSDResponse, error) GetFeeQuoterDestChainConfig(context.Context, *GetFeeQuoterDestChainConfigRequest) (*GetFeeQuoterDestChainConfigResponse, error) + // USDCMessageReader methods + MessagesByTokenID(context.Context, *MessagesByTokenIDRequest) (*MessagesByTokenIDResponse, error) + // PriceReader methods + GetFeedPricesUSD(context.Context, *GetFeedPricesUSDRequest) (*GetFeedPricesUSDResponse, error) + GetFeeQuoterTokenUpdates(context.Context, *GetFeeQuoterTokenUpdatesRequest) (*GetFeeQuoterTokenUpdatesResponse, error) mustEmbedUnimplementedChainAccessorServer() } @@ -300,6 +343,15 @@ func (UnimplementedChainAccessorServer) GetTokenPriceUSD(context.Context, *GetTo func (UnimplementedChainAccessorServer) GetFeeQuoterDestChainConfig(context.Context, *GetFeeQuoterDestChainConfigRequest) (*GetFeeQuoterDestChainConfigResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method GetFeeQuoterDestChainConfig not implemented") } +func (UnimplementedChainAccessorServer) MessagesByTokenID(context.Context, *MessagesByTokenIDRequest) (*MessagesByTokenIDResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method MessagesByTokenID not implemented") +} +func (UnimplementedChainAccessorServer) GetFeedPricesUSD(context.Context, *GetFeedPricesUSDRequest) (*GetFeedPricesUSDResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetFeedPricesUSD not implemented") +} +func (UnimplementedChainAccessorServer) GetFeeQuoterTokenUpdates(context.Context, *GetFeeQuoterTokenUpdatesRequest) (*GetFeeQuoterTokenUpdatesResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetFeeQuoterTokenUpdates not implemented") +} func (UnimplementedChainAccessorServer) mustEmbedUnimplementedChainAccessorServer() {} func (UnimplementedChainAccessorServer) testEmbeddedByValue() {} @@ -591,6 +643,60 @@ func _ChainAccessor_GetFeeQuoterDestChainConfig_Handler(srv interface{}, ctx con return interceptor(ctx, in, info, handler) } +func _ChainAccessor_MessagesByTokenID_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(MessagesByTokenIDRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(ChainAccessorServer).MessagesByTokenID(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: ChainAccessor_MessagesByTokenID_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(ChainAccessorServer).MessagesByTokenID(ctx, req.(*MessagesByTokenIDRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _ChainAccessor_GetFeedPricesUSD_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(GetFeedPricesUSDRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(ChainAccessorServer).GetFeedPricesUSD(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: ChainAccessor_GetFeedPricesUSD_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(ChainAccessorServer).GetFeedPricesUSD(ctx, req.(*GetFeedPricesUSDRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _ChainAccessor_GetFeeQuoterTokenUpdates_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(GetFeeQuoterTokenUpdatesRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(ChainAccessorServer).GetFeeQuoterTokenUpdates(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: ChainAccessor_GetFeeQuoterTokenUpdates_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(ChainAccessorServer).GetFeeQuoterTokenUpdates(ctx, req.(*GetFeeQuoterTokenUpdatesRequest)) + } + return interceptor(ctx, in, info, handler) +} + // ChainAccessor_ServiceDesc is the grpc.ServiceDesc for ChainAccessor service. // It's only intended for direct use with grpc.RegisterService, // and not to be introspected or modified (even as a copy) @@ -658,6 +764,18 @@ var ChainAccessor_ServiceDesc = grpc.ServiceDesc{ MethodName: "GetFeeQuoterDestChainConfig", Handler: _ChainAccessor_GetFeeQuoterDestChainConfig_Handler, }, + { + MethodName: "MessagesByTokenID", + Handler: _ChainAccessor_MessagesByTokenID_Handler, + }, + { + MethodName: "GetFeedPricesUSD", + Handler: _ChainAccessor_GetFeedPricesUSD_Handler, + }, + { + MethodName: "GetFeeQuoterTokenUpdates", + Handler: _ChainAccessor_GetFeeQuoterTokenUpdates_Handler, + }, }, Streams: []grpc.StreamDesc{}, Metadata: "chainaccessor.proto", diff --git a/pkg/loop/internal/pb/relayer.pb.go b/pkg/loop/internal/pb/relayer.pb.go index afbfc3f6d..ad25ffa51 100644 --- a/pkg/loop/internal/pb/relayer.pb.go +++ b/pkg/loop/internal/pb/relayer.pb.go @@ -280,6 +280,7 @@ type CCIPProviderArgs struct { ChainWriterConfig []byte `protobuf:"bytes,3,opt,name=chainWriterConfig,proto3" json:"chainWriterConfig,omitempty"` OffRampAddress string `protobuf:"bytes,4,opt,name=OffRampAddress,proto3" json:"OffRampAddress,omitempty"` PluginType uint32 `protobuf:"varint,5,opt,name=pluginType,proto3" json:"pluginType,omitempty"` + SyncedContracts []*SyncContract `protobuf:"bytes,6,rep,name=syncedContracts,proto3" json:"syncedContracts,omitempty"` // Previously synced contracts to restore unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache } @@ -349,6 +350,65 @@ func (x *CCIPProviderArgs) GetPluginType() uint32 { return 0 } +func (x *CCIPProviderArgs) GetSyncedContracts() []*SyncContract { + if x != nil { + return x.SyncedContracts + } + return nil +} + +type SyncContract struct { + state protoimpl.MessageState `protogen:"open.v1"` + ContractName string `protobuf:"bytes,1,opt,name=contractName,proto3" json:"contractName,omitempty"` + ContractAddress []byte `protobuf:"bytes,2,opt,name=contractAddress,proto3" json:"contractAddress,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *SyncContract) Reset() { + *x = SyncContract{} + mi := &file_loop_internal_pb_relayer_proto_msgTypes[5] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *SyncContract) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*SyncContract) ProtoMessage() {} + +func (x *SyncContract) ProtoReflect() protoreflect.Message { + mi := &file_loop_internal_pb_relayer_proto_msgTypes[5] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use SyncContract.ProtoReflect.Descriptor instead. +func (*SyncContract) Descriptor() ([]byte, []int) { + return file_loop_internal_pb_relayer_proto_rawDescGZIP(), []int{5} +} + +func (x *SyncContract) GetContractName() string { + if x != nil { + return x.ContractName + } + return "" +} + +func (x *SyncContract) GetContractAddress() []byte { + if x != nil { + return x.ContractAddress + } + return nil +} + // NewContractWriterRequest has request parameters for [github.com/smartcontractkit/chainlink-common/pkg/loop.Relayer.NewContractWriter]. type NewContractWriterRequest struct { state protoimpl.MessageState `protogen:"open.v1"` @@ -359,7 +419,7 @@ type NewContractWriterRequest struct { func (x *NewContractWriterRequest) Reset() { *x = NewContractWriterRequest{} - mi := &file_loop_internal_pb_relayer_proto_msgTypes[5] + mi := &file_loop_internal_pb_relayer_proto_msgTypes[6] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -371,7 +431,7 @@ func (x *NewContractWriterRequest) String() string { func (*NewContractWriterRequest) ProtoMessage() {} func (x *NewContractWriterRequest) ProtoReflect() protoreflect.Message { - mi := &file_loop_internal_pb_relayer_proto_msgTypes[5] + mi := &file_loop_internal_pb_relayer_proto_msgTypes[6] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -384,7 +444,7 @@ func (x *NewContractWriterRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use NewContractWriterRequest.ProtoReflect.Descriptor instead. func (*NewContractWriterRequest) Descriptor() ([]byte, []int) { - return file_loop_internal_pb_relayer_proto_rawDescGZIP(), []int{5} + return file_loop_internal_pb_relayer_proto_rawDescGZIP(), []int{6} } func (x *NewContractWriterRequest) GetContractWriterConfig() []byte { @@ -404,7 +464,7 @@ type NewContractWriterReply struct { func (x *NewContractWriterReply) Reset() { *x = NewContractWriterReply{} - mi := &file_loop_internal_pb_relayer_proto_msgTypes[6] + mi := &file_loop_internal_pb_relayer_proto_msgTypes[7] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -416,7 +476,7 @@ func (x *NewContractWriterReply) String() string { func (*NewContractWriterReply) ProtoMessage() {} func (x *NewContractWriterReply) ProtoReflect() protoreflect.Message { - mi := &file_loop_internal_pb_relayer_proto_msgTypes[6] + mi := &file_loop_internal_pb_relayer_proto_msgTypes[7] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -429,7 +489,7 @@ func (x *NewContractWriterReply) ProtoReflect() protoreflect.Message { // Deprecated: Use NewContractWriterReply.ProtoReflect.Descriptor instead. func (*NewContractWriterReply) Descriptor() ([]byte, []int) { - return file_loop_internal_pb_relayer_proto_rawDescGZIP(), []int{6} + return file_loop_internal_pb_relayer_proto_rawDescGZIP(), []int{7} } func (x *NewContractWriterReply) GetContractWriterID() uint32 { @@ -449,7 +509,7 @@ type NewContractReaderRequest struct { func (x *NewContractReaderRequest) Reset() { *x = NewContractReaderRequest{} - mi := &file_loop_internal_pb_relayer_proto_msgTypes[7] + mi := &file_loop_internal_pb_relayer_proto_msgTypes[8] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -461,7 +521,7 @@ func (x *NewContractReaderRequest) String() string { func (*NewContractReaderRequest) ProtoMessage() {} func (x *NewContractReaderRequest) ProtoReflect() protoreflect.Message { - mi := &file_loop_internal_pb_relayer_proto_msgTypes[7] + mi := &file_loop_internal_pb_relayer_proto_msgTypes[8] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -474,7 +534,7 @@ func (x *NewContractReaderRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use NewContractReaderRequest.ProtoReflect.Descriptor instead. func (*NewContractReaderRequest) Descriptor() ([]byte, []int) { - return file_loop_internal_pb_relayer_proto_rawDescGZIP(), []int{7} + return file_loop_internal_pb_relayer_proto_rawDescGZIP(), []int{8} } func (x *NewContractReaderRequest) GetContractReaderConfig() []byte { @@ -494,7 +554,7 @@ type NewContractReaderReply struct { func (x *NewContractReaderReply) Reset() { *x = NewContractReaderReply{} - mi := &file_loop_internal_pb_relayer_proto_msgTypes[8] + mi := &file_loop_internal_pb_relayer_proto_msgTypes[9] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -506,7 +566,7 @@ func (x *NewContractReaderReply) String() string { func (*NewContractReaderReply) ProtoMessage() {} func (x *NewContractReaderReply) ProtoReflect() protoreflect.Message { - mi := &file_loop_internal_pb_relayer_proto_msgTypes[8] + mi := &file_loop_internal_pb_relayer_proto_msgTypes[9] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -519,7 +579,7 @@ func (x *NewContractReaderReply) ProtoReflect() protoreflect.Message { // Deprecated: Use NewContractReaderReply.ProtoReflect.Descriptor instead. func (*NewContractReaderReply) Descriptor() ([]byte, []int) { - return file_loop_internal_pb_relayer_proto_rawDescGZIP(), []int{8} + return file_loop_internal_pb_relayer_proto_rawDescGZIP(), []int{9} } func (x *NewContractReaderReply) GetContractReaderID() uint32 { @@ -540,7 +600,7 @@ type NewPluginProviderRequest struct { func (x *NewPluginProviderRequest) Reset() { *x = NewPluginProviderRequest{} - mi := &file_loop_internal_pb_relayer_proto_msgTypes[9] + mi := &file_loop_internal_pb_relayer_proto_msgTypes[10] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -552,7 +612,7 @@ func (x *NewPluginProviderRequest) String() string { func (*NewPluginProviderRequest) ProtoMessage() {} func (x *NewPluginProviderRequest) ProtoReflect() protoreflect.Message { - mi := &file_loop_internal_pb_relayer_proto_msgTypes[9] + mi := &file_loop_internal_pb_relayer_proto_msgTypes[10] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -565,7 +625,7 @@ func (x *NewPluginProviderRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use NewPluginProviderRequest.ProtoReflect.Descriptor instead. func (*NewPluginProviderRequest) Descriptor() ([]byte, []int) { - return file_loop_internal_pb_relayer_proto_rawDescGZIP(), []int{9} + return file_loop_internal_pb_relayer_proto_rawDescGZIP(), []int{10} } func (x *NewPluginProviderRequest) GetRelayArgs() *RelayArgs { @@ -592,7 +652,7 @@ type NewPluginProviderReply struct { func (x *NewPluginProviderReply) Reset() { *x = NewPluginProviderReply{} - mi := &file_loop_internal_pb_relayer_proto_msgTypes[10] + mi := &file_loop_internal_pb_relayer_proto_msgTypes[11] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -604,7 +664,7 @@ func (x *NewPluginProviderReply) String() string { func (*NewPluginProviderReply) ProtoMessage() {} func (x *NewPluginProviderReply) ProtoReflect() protoreflect.Message { - mi := &file_loop_internal_pb_relayer_proto_msgTypes[10] + mi := &file_loop_internal_pb_relayer_proto_msgTypes[11] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -617,7 +677,7 @@ func (x *NewPluginProviderReply) ProtoReflect() protoreflect.Message { // Deprecated: Use NewPluginProviderReply.ProtoReflect.Descriptor instead. func (*NewPluginProviderReply) Descriptor() ([]byte, []int) { - return file_loop_internal_pb_relayer_proto_rawDescGZIP(), []int{10} + return file_loop_internal_pb_relayer_proto_rawDescGZIP(), []int{11} } func (x *NewPluginProviderReply) GetPluginProviderID() uint32 { @@ -637,7 +697,7 @@ type NewConfigProviderRequest struct { func (x *NewConfigProviderRequest) Reset() { *x = NewConfigProviderRequest{} - mi := &file_loop_internal_pb_relayer_proto_msgTypes[11] + mi := &file_loop_internal_pb_relayer_proto_msgTypes[12] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -649,7 +709,7 @@ func (x *NewConfigProviderRequest) String() string { func (*NewConfigProviderRequest) ProtoMessage() {} func (x *NewConfigProviderRequest) ProtoReflect() protoreflect.Message { - mi := &file_loop_internal_pb_relayer_proto_msgTypes[11] + mi := &file_loop_internal_pb_relayer_proto_msgTypes[12] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -662,7 +722,7 @@ func (x *NewConfigProviderRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use NewConfigProviderRequest.ProtoReflect.Descriptor instead. func (*NewConfigProviderRequest) Descriptor() ([]byte, []int) { - return file_loop_internal_pb_relayer_proto_rawDescGZIP(), []int{11} + return file_loop_internal_pb_relayer_proto_rawDescGZIP(), []int{12} } func (x *NewConfigProviderRequest) GetRelayArgs() *RelayArgs { @@ -682,7 +742,7 @@ type NewConfigProviderReply struct { func (x *NewConfigProviderReply) Reset() { *x = NewConfigProviderReply{} - mi := &file_loop_internal_pb_relayer_proto_msgTypes[12] + mi := &file_loop_internal_pb_relayer_proto_msgTypes[13] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -694,7 +754,7 @@ func (x *NewConfigProviderReply) String() string { func (*NewConfigProviderReply) ProtoMessage() {} func (x *NewConfigProviderReply) ProtoReflect() protoreflect.Message { - mi := &file_loop_internal_pb_relayer_proto_msgTypes[12] + mi := &file_loop_internal_pb_relayer_proto_msgTypes[13] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -707,7 +767,7 @@ func (x *NewConfigProviderReply) ProtoReflect() protoreflect.Message { // Deprecated: Use NewConfigProviderReply.ProtoReflect.Descriptor instead. func (*NewConfigProviderReply) Descriptor() ([]byte, []int) { - return file_loop_internal_pb_relayer_proto_rawDescGZIP(), []int{12} + return file_loop_internal_pb_relayer_proto_rawDescGZIP(), []int{13} } func (x *NewConfigProviderReply) GetConfigProviderID() uint32 { @@ -727,7 +787,7 @@ type NewCCIPProviderRequest struct { func (x *NewCCIPProviderRequest) Reset() { *x = NewCCIPProviderRequest{} - mi := &file_loop_internal_pb_relayer_proto_msgTypes[13] + mi := &file_loop_internal_pb_relayer_proto_msgTypes[14] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -739,7 +799,7 @@ func (x *NewCCIPProviderRequest) String() string { func (*NewCCIPProviderRequest) ProtoMessage() {} func (x *NewCCIPProviderRequest) ProtoReflect() protoreflect.Message { - mi := &file_loop_internal_pb_relayer_proto_msgTypes[13] + mi := &file_loop_internal_pb_relayer_proto_msgTypes[14] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -752,7 +812,7 @@ func (x *NewCCIPProviderRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use NewCCIPProviderRequest.ProtoReflect.Descriptor instead. func (*NewCCIPProviderRequest) Descriptor() ([]byte, []int) { - return file_loop_internal_pb_relayer_proto_rawDescGZIP(), []int{13} + return file_loop_internal_pb_relayer_proto_rawDescGZIP(), []int{14} } func (x *NewCCIPProviderRequest) GetCcipProviderArgs() *CCIPProviderArgs { @@ -772,7 +832,7 @@ type NewCCIPProviderReply struct { func (x *NewCCIPProviderReply) Reset() { *x = NewCCIPProviderReply{} - mi := &file_loop_internal_pb_relayer_proto_msgTypes[14] + mi := &file_loop_internal_pb_relayer_proto_msgTypes[15] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -784,7 +844,7 @@ func (x *NewCCIPProviderReply) String() string { func (*NewCCIPProviderReply) ProtoMessage() {} func (x *NewCCIPProviderReply) ProtoReflect() protoreflect.Message { - mi := &file_loop_internal_pb_relayer_proto_msgTypes[14] + mi := &file_loop_internal_pb_relayer_proto_msgTypes[15] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -797,7 +857,7 @@ func (x *NewCCIPProviderReply) ProtoReflect() protoreflect.Message { // Deprecated: Use NewCCIPProviderReply.ProtoReflect.Descriptor instead. func (*NewCCIPProviderReply) Descriptor() ([]byte, []int) { - return file_loop_internal_pb_relayer_proto_rawDescGZIP(), []int{14} + return file_loop_internal_pb_relayer_proto_rawDescGZIP(), []int{15} } func (x *NewCCIPProviderReply) GetCcipProviderID() uint32 { @@ -815,7 +875,7 @@ type LatestHeadRequest struct { func (x *LatestHeadRequest) Reset() { *x = LatestHeadRequest{} - mi := &file_loop_internal_pb_relayer_proto_msgTypes[15] + mi := &file_loop_internal_pb_relayer_proto_msgTypes[16] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -827,7 +887,7 @@ func (x *LatestHeadRequest) String() string { func (*LatestHeadRequest) ProtoMessage() {} func (x *LatestHeadRequest) ProtoReflect() protoreflect.Message { - mi := &file_loop_internal_pb_relayer_proto_msgTypes[15] + mi := &file_loop_internal_pb_relayer_proto_msgTypes[16] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -840,7 +900,7 @@ func (x *LatestHeadRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use LatestHeadRequest.ProtoReflect.Descriptor instead. func (*LatestHeadRequest) Descriptor() ([]byte, []int) { - return file_loop_internal_pb_relayer_proto_rawDescGZIP(), []int{15} + return file_loop_internal_pb_relayer_proto_rawDescGZIP(), []int{16} } // LatestHeadReply has return arguments for [github.com/smartcontractkit/chainlink-common/pkg/loop.Relayer.LatestHeadReply]. @@ -853,7 +913,7 @@ type LatestHeadReply struct { func (x *LatestHeadReply) Reset() { *x = LatestHeadReply{} - mi := &file_loop_internal_pb_relayer_proto_msgTypes[16] + mi := &file_loop_internal_pb_relayer_proto_msgTypes[17] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -865,7 +925,7 @@ func (x *LatestHeadReply) String() string { func (*LatestHeadReply) ProtoMessage() {} func (x *LatestHeadReply) ProtoReflect() protoreflect.Message { - mi := &file_loop_internal_pb_relayer_proto_msgTypes[16] + mi := &file_loop_internal_pb_relayer_proto_msgTypes[17] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -878,7 +938,7 @@ func (x *LatestHeadReply) ProtoReflect() protoreflect.Message { // Deprecated: Use LatestHeadReply.ProtoReflect.Descriptor instead. func (*LatestHeadReply) Descriptor() ([]byte, []int) { - return file_loop_internal_pb_relayer_proto_rawDescGZIP(), []int{16} + return file_loop_internal_pb_relayer_proto_rawDescGZIP(), []int{17} } func (x *LatestHeadReply) GetHead() *Head { @@ -896,7 +956,7 @@ type GetChainStatusRequest struct { func (x *GetChainStatusRequest) Reset() { *x = GetChainStatusRequest{} - mi := &file_loop_internal_pb_relayer_proto_msgTypes[17] + mi := &file_loop_internal_pb_relayer_proto_msgTypes[18] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -908,7 +968,7 @@ func (x *GetChainStatusRequest) String() string { func (*GetChainStatusRequest) ProtoMessage() {} func (x *GetChainStatusRequest) ProtoReflect() protoreflect.Message { - mi := &file_loop_internal_pb_relayer_proto_msgTypes[17] + mi := &file_loop_internal_pb_relayer_proto_msgTypes[18] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -921,7 +981,7 @@ func (x *GetChainStatusRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use GetChainStatusRequest.ProtoReflect.Descriptor instead. func (*GetChainStatusRequest) Descriptor() ([]byte, []int) { - return file_loop_internal_pb_relayer_proto_rawDescGZIP(), []int{17} + return file_loop_internal_pb_relayer_proto_rawDescGZIP(), []int{18} } // ChainStatusReply has return arguments for [github.com/smartcontractkit/chainlink-common/pkg/loop.Relayer.ChainStatus]. @@ -934,7 +994,7 @@ type GetChainStatusReply struct { func (x *GetChainStatusReply) Reset() { *x = GetChainStatusReply{} - mi := &file_loop_internal_pb_relayer_proto_msgTypes[18] + mi := &file_loop_internal_pb_relayer_proto_msgTypes[19] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -946,7 +1006,7 @@ func (x *GetChainStatusReply) String() string { func (*GetChainStatusReply) ProtoMessage() {} func (x *GetChainStatusReply) ProtoReflect() protoreflect.Message { - mi := &file_loop_internal_pb_relayer_proto_msgTypes[18] + mi := &file_loop_internal_pb_relayer_proto_msgTypes[19] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -959,7 +1019,7 @@ func (x *GetChainStatusReply) ProtoReflect() protoreflect.Message { // Deprecated: Use GetChainStatusReply.ProtoReflect.Descriptor instead. func (*GetChainStatusReply) Descriptor() ([]byte, []int) { - return file_loop_internal_pb_relayer_proto_rawDescGZIP(), []int{18} + return file_loop_internal_pb_relayer_proto_rawDescGZIP(), []int{19} } func (x *GetChainStatusReply) GetChain() *ChainStatus { @@ -977,7 +1037,7 @@ type GetChainInfoRequest struct { func (x *GetChainInfoRequest) Reset() { *x = GetChainInfoRequest{} - mi := &file_loop_internal_pb_relayer_proto_msgTypes[19] + mi := &file_loop_internal_pb_relayer_proto_msgTypes[20] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -989,7 +1049,7 @@ func (x *GetChainInfoRequest) String() string { func (*GetChainInfoRequest) ProtoMessage() {} func (x *GetChainInfoRequest) ProtoReflect() protoreflect.Message { - mi := &file_loop_internal_pb_relayer_proto_msgTypes[19] + mi := &file_loop_internal_pb_relayer_proto_msgTypes[20] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1002,7 +1062,7 @@ func (x *GetChainInfoRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use GetChainInfoRequest.ProtoReflect.Descriptor instead. func (*GetChainInfoRequest) Descriptor() ([]byte, []int) { - return file_loop_internal_pb_relayer_proto_rawDescGZIP(), []int{19} + return file_loop_internal_pb_relayer_proto_rawDescGZIP(), []int{20} } // GetChainInfoReply has return arguments for [github.com/smartcontractkit/chainlink-common/pkg/loop.Relayer.GetChainInfo]. @@ -1015,7 +1075,7 @@ type GetChainInfoReply struct { func (x *GetChainInfoReply) Reset() { *x = GetChainInfoReply{} - mi := &file_loop_internal_pb_relayer_proto_msgTypes[20] + mi := &file_loop_internal_pb_relayer_proto_msgTypes[21] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1027,7 +1087,7 @@ func (x *GetChainInfoReply) String() string { func (*GetChainInfoReply) ProtoMessage() {} func (x *GetChainInfoReply) ProtoReflect() protoreflect.Message { - mi := &file_loop_internal_pb_relayer_proto_msgTypes[20] + mi := &file_loop_internal_pb_relayer_proto_msgTypes[21] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1040,7 +1100,7 @@ func (x *GetChainInfoReply) ProtoReflect() protoreflect.Message { // Deprecated: Use GetChainInfoReply.ProtoReflect.Descriptor instead. func (*GetChainInfoReply) Descriptor() ([]byte, []int) { - return file_loop_internal_pb_relayer_proto_rawDescGZIP(), []int{20} + return file_loop_internal_pb_relayer_proto_rawDescGZIP(), []int{21} } func (x *GetChainInfoReply) GetChainInfo() *ChainInfo { @@ -1062,7 +1122,7 @@ type ChainStatus struct { func (x *ChainStatus) Reset() { *x = ChainStatus{} - mi := &file_loop_internal_pb_relayer_proto_msgTypes[21] + mi := &file_loop_internal_pb_relayer_proto_msgTypes[22] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1074,7 +1134,7 @@ func (x *ChainStatus) String() string { func (*ChainStatus) ProtoMessage() {} func (x *ChainStatus) ProtoReflect() protoreflect.Message { - mi := &file_loop_internal_pb_relayer_proto_msgTypes[21] + mi := &file_loop_internal_pb_relayer_proto_msgTypes[22] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1087,7 +1147,7 @@ func (x *ChainStatus) ProtoReflect() protoreflect.Message { // Deprecated: Use ChainStatus.ProtoReflect.Descriptor instead. func (*ChainStatus) Descriptor() ([]byte, []int) { - return file_loop_internal_pb_relayer_proto_rawDescGZIP(), []int{21} + return file_loop_internal_pb_relayer_proto_rawDescGZIP(), []int{22} } func (x *ChainStatus) GetId() string { @@ -1124,7 +1184,7 @@ type ChainInfo struct { func (x *ChainInfo) Reset() { *x = ChainInfo{} - mi := &file_loop_internal_pb_relayer_proto_msgTypes[22] + mi := &file_loop_internal_pb_relayer_proto_msgTypes[23] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1136,7 +1196,7 @@ func (x *ChainInfo) String() string { func (*ChainInfo) ProtoMessage() {} func (x *ChainInfo) ProtoReflect() protoreflect.Message { - mi := &file_loop_internal_pb_relayer_proto_msgTypes[22] + mi := &file_loop_internal_pb_relayer_proto_msgTypes[23] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1149,7 +1209,7 @@ func (x *ChainInfo) ProtoReflect() protoreflect.Message { // Deprecated: Use ChainInfo.ProtoReflect.Descriptor instead. func (*ChainInfo) Descriptor() ([]byte, []int) { - return file_loop_internal_pb_relayer_proto_rawDescGZIP(), []int{22} + return file_loop_internal_pb_relayer_proto_rawDescGZIP(), []int{23} } func (x *ChainInfo) GetFamilyName() string { @@ -1191,7 +1251,7 @@ type ListNodeStatusesRequest struct { func (x *ListNodeStatusesRequest) Reset() { *x = ListNodeStatusesRequest{} - mi := &file_loop_internal_pb_relayer_proto_msgTypes[23] + mi := &file_loop_internal_pb_relayer_proto_msgTypes[24] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1203,7 +1263,7 @@ func (x *ListNodeStatusesRequest) String() string { func (*ListNodeStatusesRequest) ProtoMessage() {} func (x *ListNodeStatusesRequest) ProtoReflect() protoreflect.Message { - mi := &file_loop_internal_pb_relayer_proto_msgTypes[23] + mi := &file_loop_internal_pb_relayer_proto_msgTypes[24] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1216,7 +1276,7 @@ func (x *ListNodeStatusesRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ListNodeStatusesRequest.ProtoReflect.Descriptor instead. func (*ListNodeStatusesRequest) Descriptor() ([]byte, []int) { - return file_loop_internal_pb_relayer_proto_rawDescGZIP(), []int{23} + return file_loop_internal_pb_relayer_proto_rawDescGZIP(), []int{24} } func (x *ListNodeStatusesRequest) GetPageSize() int32 { @@ -1245,7 +1305,7 @@ type ListNodeStatusesReply struct { func (x *ListNodeStatusesReply) Reset() { *x = ListNodeStatusesReply{} - mi := &file_loop_internal_pb_relayer_proto_msgTypes[24] + mi := &file_loop_internal_pb_relayer_proto_msgTypes[25] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1257,7 +1317,7 @@ func (x *ListNodeStatusesReply) String() string { func (*ListNodeStatusesReply) ProtoMessage() {} func (x *ListNodeStatusesReply) ProtoReflect() protoreflect.Message { - mi := &file_loop_internal_pb_relayer_proto_msgTypes[24] + mi := &file_loop_internal_pb_relayer_proto_msgTypes[25] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1270,7 +1330,7 @@ func (x *ListNodeStatusesReply) ProtoReflect() protoreflect.Message { // Deprecated: Use ListNodeStatusesReply.ProtoReflect.Descriptor instead. func (*ListNodeStatusesReply) Descriptor() ([]byte, []int) { - return file_loop_internal_pb_relayer_proto_rawDescGZIP(), []int{24} + return file_loop_internal_pb_relayer_proto_rawDescGZIP(), []int{25} } func (x *ListNodeStatusesReply) GetNodes() []*NodeStatus { @@ -1307,7 +1367,7 @@ type NodeStatus struct { func (x *NodeStatus) Reset() { *x = NodeStatus{} - mi := &file_loop_internal_pb_relayer_proto_msgTypes[25] + mi := &file_loop_internal_pb_relayer_proto_msgTypes[26] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1319,7 +1379,7 @@ func (x *NodeStatus) String() string { func (*NodeStatus) ProtoMessage() {} func (x *NodeStatus) ProtoReflect() protoreflect.Message { - mi := &file_loop_internal_pb_relayer_proto_msgTypes[25] + mi := &file_loop_internal_pb_relayer_proto_msgTypes[26] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1332,7 +1392,7 @@ func (x *NodeStatus) ProtoReflect() protoreflect.Message { // Deprecated: Use NodeStatus.ProtoReflect.Descriptor instead. func (*NodeStatus) Descriptor() ([]byte, []int) { - return file_loop_internal_pb_relayer_proto_rawDescGZIP(), []int{25} + return file_loop_internal_pb_relayer_proto_rawDescGZIP(), []int{26} } func (x *NodeStatus) GetChainID() string { @@ -1373,7 +1433,7 @@ type ReplayRequest struct { func (x *ReplayRequest) Reset() { *x = ReplayRequest{} - mi := &file_loop_internal_pb_relayer_proto_msgTypes[26] + mi := &file_loop_internal_pb_relayer_proto_msgTypes[27] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1385,7 +1445,7 @@ func (x *ReplayRequest) String() string { func (*ReplayRequest) ProtoMessage() {} func (x *ReplayRequest) ProtoReflect() protoreflect.Message { - mi := &file_loop_internal_pb_relayer_proto_msgTypes[26] + mi := &file_loop_internal_pb_relayer_proto_msgTypes[27] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1398,7 +1458,7 @@ func (x *ReplayRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ReplayRequest.ProtoReflect.Descriptor instead. func (*ReplayRequest) Descriptor() ([]byte, []int) { - return file_loop_internal_pb_relayer_proto_rawDescGZIP(), []int{26} + return file_loop_internal_pb_relayer_proto_rawDescGZIP(), []int{27} } func (x *ReplayRequest) GetFromBlock() string { @@ -1428,7 +1488,7 @@ type TransactionRequest struct { func (x *TransactionRequest) Reset() { *x = TransactionRequest{} - mi := &file_loop_internal_pb_relayer_proto_msgTypes[27] + mi := &file_loop_internal_pb_relayer_proto_msgTypes[28] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1440,7 +1500,7 @@ func (x *TransactionRequest) String() string { func (*TransactionRequest) ProtoMessage() {} func (x *TransactionRequest) ProtoReflect() protoreflect.Message { - mi := &file_loop_internal_pb_relayer_proto_msgTypes[27] + mi := &file_loop_internal_pb_relayer_proto_msgTypes[28] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1453,7 +1513,7 @@ func (x *TransactionRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use TransactionRequest.ProtoReflect.Descriptor instead. func (*TransactionRequest) Descriptor() ([]byte, []int) { - return file_loop_internal_pb_relayer_proto_rawDescGZIP(), []int{27} + return file_loop_internal_pb_relayer_proto_rawDescGZIP(), []int{28} } func (x *TransactionRequest) GetFrom() string { @@ -1501,7 +1561,7 @@ type ContractConfig struct { func (x *ContractConfig) Reset() { *x = ContractConfig{} - mi := &file_loop_internal_pb_relayer_proto_msgTypes[28] + mi := &file_loop_internal_pb_relayer_proto_msgTypes[29] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1513,7 +1573,7 @@ func (x *ContractConfig) String() string { func (*ContractConfig) ProtoMessage() {} func (x *ContractConfig) ProtoReflect() protoreflect.Message { - mi := &file_loop_internal_pb_relayer_proto_msgTypes[28] + mi := &file_loop_internal_pb_relayer_proto_msgTypes[29] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1526,7 +1586,7 @@ func (x *ContractConfig) ProtoReflect() protoreflect.Message { // Deprecated: Use ContractConfig.ProtoReflect.Descriptor instead. func (*ContractConfig) Descriptor() ([]byte, []int) { - return file_loop_internal_pb_relayer_proto_rawDescGZIP(), []int{28} + return file_loop_internal_pb_relayer_proto_rawDescGZIP(), []int{29} } func (x *ContractConfig) GetConfigDigest() []byte { @@ -1595,7 +1655,7 @@ type ConfigDigestRequest struct { func (x *ConfigDigestRequest) Reset() { *x = ConfigDigestRequest{} - mi := &file_loop_internal_pb_relayer_proto_msgTypes[29] + mi := &file_loop_internal_pb_relayer_proto_msgTypes[30] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1607,7 +1667,7 @@ func (x *ConfigDigestRequest) String() string { func (*ConfigDigestRequest) ProtoMessage() {} func (x *ConfigDigestRequest) ProtoReflect() protoreflect.Message { - mi := &file_loop_internal_pb_relayer_proto_msgTypes[29] + mi := &file_loop_internal_pb_relayer_proto_msgTypes[30] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1620,7 +1680,7 @@ func (x *ConfigDigestRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ConfigDigestRequest.ProtoReflect.Descriptor instead. func (*ConfigDigestRequest) Descriptor() ([]byte, []int) { - return file_loop_internal_pb_relayer_proto_rawDescGZIP(), []int{29} + return file_loop_internal_pb_relayer_proto_rawDescGZIP(), []int{30} } func (x *ConfigDigestRequest) GetContractConfig() *ContractConfig { @@ -1640,7 +1700,7 @@ type ConfigDigestReply struct { func (x *ConfigDigestReply) Reset() { *x = ConfigDigestReply{} - mi := &file_loop_internal_pb_relayer_proto_msgTypes[30] + mi := &file_loop_internal_pb_relayer_proto_msgTypes[31] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1652,7 +1712,7 @@ func (x *ConfigDigestReply) String() string { func (*ConfigDigestReply) ProtoMessage() {} func (x *ConfigDigestReply) ProtoReflect() protoreflect.Message { - mi := &file_loop_internal_pb_relayer_proto_msgTypes[30] + mi := &file_loop_internal_pb_relayer_proto_msgTypes[31] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1665,7 +1725,7 @@ func (x *ConfigDigestReply) ProtoReflect() protoreflect.Message { // Deprecated: Use ConfigDigestReply.ProtoReflect.Descriptor instead. func (*ConfigDigestReply) Descriptor() ([]byte, []int) { - return file_loop_internal_pb_relayer_proto_rawDescGZIP(), []int{30} + return file_loop_internal_pb_relayer_proto_rawDescGZIP(), []int{31} } func (x *ConfigDigestReply) GetConfigDigest() []byte { @@ -1683,7 +1743,7 @@ type ConfigDigestPrefixRequest struct { func (x *ConfigDigestPrefixRequest) Reset() { *x = ConfigDigestPrefixRequest{} - mi := &file_loop_internal_pb_relayer_proto_msgTypes[31] + mi := &file_loop_internal_pb_relayer_proto_msgTypes[32] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1695,7 +1755,7 @@ func (x *ConfigDigestPrefixRequest) String() string { func (*ConfigDigestPrefixRequest) ProtoMessage() {} func (x *ConfigDigestPrefixRequest) ProtoReflect() protoreflect.Message { - mi := &file_loop_internal_pb_relayer_proto_msgTypes[31] + mi := &file_loop_internal_pb_relayer_proto_msgTypes[32] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1708,7 +1768,7 @@ func (x *ConfigDigestPrefixRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ConfigDigestPrefixRequest.ProtoReflect.Descriptor instead. func (*ConfigDigestPrefixRequest) Descriptor() ([]byte, []int) { - return file_loop_internal_pb_relayer_proto_rawDescGZIP(), []int{31} + return file_loop_internal_pb_relayer_proto_rawDescGZIP(), []int{32} } // ConfigDigestPrefixReply has return arguments for [github.com/smartcontractkit/libocr/offchainreporting2plus/types.OffchainConfigDigester.ConfigDigestPrefix]. @@ -1721,7 +1781,7 @@ type ConfigDigestPrefixReply struct { func (x *ConfigDigestPrefixReply) Reset() { *x = ConfigDigestPrefixReply{} - mi := &file_loop_internal_pb_relayer_proto_msgTypes[32] + mi := &file_loop_internal_pb_relayer_proto_msgTypes[33] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1733,7 +1793,7 @@ func (x *ConfigDigestPrefixReply) String() string { func (*ConfigDigestPrefixReply) ProtoMessage() {} func (x *ConfigDigestPrefixReply) ProtoReflect() protoreflect.Message { - mi := &file_loop_internal_pb_relayer_proto_msgTypes[32] + mi := &file_loop_internal_pb_relayer_proto_msgTypes[33] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1746,7 +1806,7 @@ func (x *ConfigDigestPrefixReply) ProtoReflect() protoreflect.Message { // Deprecated: Use ConfigDigestPrefixReply.ProtoReflect.Descriptor instead. func (*ConfigDigestPrefixReply) Descriptor() ([]byte, []int) { - return file_loop_internal_pb_relayer_proto_rawDescGZIP(), []int{32} + return file_loop_internal_pb_relayer_proto_rawDescGZIP(), []int{33} } func (x *ConfigDigestPrefixReply) GetConfigDigestPrefix() uint32 { @@ -1764,7 +1824,7 @@ type LatestConfigDetailsRequest struct { func (x *LatestConfigDetailsRequest) Reset() { *x = LatestConfigDetailsRequest{} - mi := &file_loop_internal_pb_relayer_proto_msgTypes[33] + mi := &file_loop_internal_pb_relayer_proto_msgTypes[34] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1776,7 +1836,7 @@ func (x *LatestConfigDetailsRequest) String() string { func (*LatestConfigDetailsRequest) ProtoMessage() {} func (x *LatestConfigDetailsRequest) ProtoReflect() protoreflect.Message { - mi := &file_loop_internal_pb_relayer_proto_msgTypes[33] + mi := &file_loop_internal_pb_relayer_proto_msgTypes[34] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1789,7 +1849,7 @@ func (x *LatestConfigDetailsRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use LatestConfigDetailsRequest.ProtoReflect.Descriptor instead. func (*LatestConfigDetailsRequest) Descriptor() ([]byte, []int) { - return file_loop_internal_pb_relayer_proto_rawDescGZIP(), []int{33} + return file_loop_internal_pb_relayer_proto_rawDescGZIP(), []int{34} } // LatestConfigDetailsReply has return arguments for [github.com/smartcontractkit/libocr/offchainreporting2plus/types.ContractConfigTracker.LatestConfigDetails]. @@ -1803,7 +1863,7 @@ type LatestConfigDetailsReply struct { func (x *LatestConfigDetailsReply) Reset() { *x = LatestConfigDetailsReply{} - mi := &file_loop_internal_pb_relayer_proto_msgTypes[34] + mi := &file_loop_internal_pb_relayer_proto_msgTypes[35] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1815,7 +1875,7 @@ func (x *LatestConfigDetailsReply) String() string { func (*LatestConfigDetailsReply) ProtoMessage() {} func (x *LatestConfigDetailsReply) ProtoReflect() protoreflect.Message { - mi := &file_loop_internal_pb_relayer_proto_msgTypes[34] + mi := &file_loop_internal_pb_relayer_proto_msgTypes[35] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1828,7 +1888,7 @@ func (x *LatestConfigDetailsReply) ProtoReflect() protoreflect.Message { // Deprecated: Use LatestConfigDetailsReply.ProtoReflect.Descriptor instead. func (*LatestConfigDetailsReply) Descriptor() ([]byte, []int) { - return file_loop_internal_pb_relayer_proto_rawDescGZIP(), []int{34} + return file_loop_internal_pb_relayer_proto_rawDescGZIP(), []int{35} } func (x *LatestConfigDetailsReply) GetChangedInBlock() uint64 { @@ -1855,7 +1915,7 @@ type LatestConfigRequest struct { func (x *LatestConfigRequest) Reset() { *x = LatestConfigRequest{} - mi := &file_loop_internal_pb_relayer_proto_msgTypes[35] + mi := &file_loop_internal_pb_relayer_proto_msgTypes[36] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1867,7 +1927,7 @@ func (x *LatestConfigRequest) String() string { func (*LatestConfigRequest) ProtoMessage() {} func (x *LatestConfigRequest) ProtoReflect() protoreflect.Message { - mi := &file_loop_internal_pb_relayer_proto_msgTypes[35] + mi := &file_loop_internal_pb_relayer_proto_msgTypes[36] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1880,7 +1940,7 @@ func (x *LatestConfigRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use LatestConfigRequest.ProtoReflect.Descriptor instead. func (*LatestConfigRequest) Descriptor() ([]byte, []int) { - return file_loop_internal_pb_relayer_proto_rawDescGZIP(), []int{35} + return file_loop_internal_pb_relayer_proto_rawDescGZIP(), []int{36} } func (x *LatestConfigRequest) GetChangedInBlock() uint64 { @@ -1900,7 +1960,7 @@ type LatestConfigReply struct { func (x *LatestConfigReply) Reset() { *x = LatestConfigReply{} - mi := &file_loop_internal_pb_relayer_proto_msgTypes[36] + mi := &file_loop_internal_pb_relayer_proto_msgTypes[37] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1912,7 +1972,7 @@ func (x *LatestConfigReply) String() string { func (*LatestConfigReply) ProtoMessage() {} func (x *LatestConfigReply) ProtoReflect() protoreflect.Message { - mi := &file_loop_internal_pb_relayer_proto_msgTypes[36] + mi := &file_loop_internal_pb_relayer_proto_msgTypes[37] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1925,7 +1985,7 @@ func (x *LatestConfigReply) ProtoReflect() protoreflect.Message { // Deprecated: Use LatestConfigReply.ProtoReflect.Descriptor instead. func (*LatestConfigReply) Descriptor() ([]byte, []int) { - return file_loop_internal_pb_relayer_proto_rawDescGZIP(), []int{36} + return file_loop_internal_pb_relayer_proto_rawDescGZIP(), []int{37} } func (x *LatestConfigReply) GetContractConfig() *ContractConfig { @@ -1943,7 +2003,7 @@ type LatestBlockHeightRequest struct { func (x *LatestBlockHeightRequest) Reset() { *x = LatestBlockHeightRequest{} - mi := &file_loop_internal_pb_relayer_proto_msgTypes[37] + mi := &file_loop_internal_pb_relayer_proto_msgTypes[38] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1955,7 +2015,7 @@ func (x *LatestBlockHeightRequest) String() string { func (*LatestBlockHeightRequest) ProtoMessage() {} func (x *LatestBlockHeightRequest) ProtoReflect() protoreflect.Message { - mi := &file_loop_internal_pb_relayer_proto_msgTypes[37] + mi := &file_loop_internal_pb_relayer_proto_msgTypes[38] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1968,7 +2028,7 @@ func (x *LatestBlockHeightRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use LatestBlockHeightRequest.ProtoReflect.Descriptor instead. func (*LatestBlockHeightRequest) Descriptor() ([]byte, []int) { - return file_loop_internal_pb_relayer_proto_rawDescGZIP(), []int{37} + return file_loop_internal_pb_relayer_proto_rawDescGZIP(), []int{38} } // LatestBlockHeightReply has return arguments for [github.com/smartcontractkit/libocr/offchainreporting2plus/types.ContractConfigTracker.LatestBlockHeightReply]. @@ -1981,7 +2041,7 @@ type LatestBlockHeightReply struct { func (x *LatestBlockHeightReply) Reset() { *x = LatestBlockHeightReply{} - mi := &file_loop_internal_pb_relayer_proto_msgTypes[38] + mi := &file_loop_internal_pb_relayer_proto_msgTypes[39] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1993,7 +2053,7 @@ func (x *LatestBlockHeightReply) String() string { func (*LatestBlockHeightReply) ProtoMessage() {} func (x *LatestBlockHeightReply) ProtoReflect() protoreflect.Message { - mi := &file_loop_internal_pb_relayer_proto_msgTypes[38] + mi := &file_loop_internal_pb_relayer_proto_msgTypes[39] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2006,7 +2066,7 @@ func (x *LatestBlockHeightReply) ProtoReflect() protoreflect.Message { // Deprecated: Use LatestBlockHeightReply.ProtoReflect.Descriptor instead. func (*LatestBlockHeightReply) Descriptor() ([]byte, []int) { - return file_loop_internal_pb_relayer_proto_rawDescGZIP(), []int{38} + return file_loop_internal_pb_relayer_proto_rawDescGZIP(), []int{39} } func (x *LatestBlockHeightReply) GetBlockHeight() uint64 { @@ -2028,7 +2088,7 @@ type ReportTimestamp struct { func (x *ReportTimestamp) Reset() { *x = ReportTimestamp{} - mi := &file_loop_internal_pb_relayer_proto_msgTypes[39] + mi := &file_loop_internal_pb_relayer_proto_msgTypes[40] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2040,7 +2100,7 @@ func (x *ReportTimestamp) String() string { func (*ReportTimestamp) ProtoMessage() {} func (x *ReportTimestamp) ProtoReflect() protoreflect.Message { - mi := &file_loop_internal_pb_relayer_proto_msgTypes[39] + mi := &file_loop_internal_pb_relayer_proto_msgTypes[40] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2053,7 +2113,7 @@ func (x *ReportTimestamp) ProtoReflect() protoreflect.Message { // Deprecated: Use ReportTimestamp.ProtoReflect.Descriptor instead. func (*ReportTimestamp) Descriptor() ([]byte, []int) { - return file_loop_internal_pb_relayer_proto_rawDescGZIP(), []int{39} + return file_loop_internal_pb_relayer_proto_rawDescGZIP(), []int{40} } func (x *ReportTimestamp) GetConfigDigest() []byte { @@ -2088,7 +2148,7 @@ type ReportContext struct { func (x *ReportContext) Reset() { *x = ReportContext{} - mi := &file_loop_internal_pb_relayer_proto_msgTypes[40] + mi := &file_loop_internal_pb_relayer_proto_msgTypes[41] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2100,7 +2160,7 @@ func (x *ReportContext) String() string { func (*ReportContext) ProtoMessage() {} func (x *ReportContext) ProtoReflect() protoreflect.Message { - mi := &file_loop_internal_pb_relayer_proto_msgTypes[40] + mi := &file_loop_internal_pb_relayer_proto_msgTypes[41] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2113,7 +2173,7 @@ func (x *ReportContext) ProtoReflect() protoreflect.Message { // Deprecated: Use ReportContext.ProtoReflect.Descriptor instead. func (*ReportContext) Descriptor() ([]byte, []int) { - return file_loop_internal_pb_relayer_proto_rawDescGZIP(), []int{40} + return file_loop_internal_pb_relayer_proto_rawDescGZIP(), []int{41} } func (x *ReportContext) GetReportTimestamp() *ReportTimestamp { @@ -2141,7 +2201,7 @@ type AttributedOnchainSignature struct { func (x *AttributedOnchainSignature) Reset() { *x = AttributedOnchainSignature{} - mi := &file_loop_internal_pb_relayer_proto_msgTypes[41] + mi := &file_loop_internal_pb_relayer_proto_msgTypes[42] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2153,7 +2213,7 @@ func (x *AttributedOnchainSignature) String() string { func (*AttributedOnchainSignature) ProtoMessage() {} func (x *AttributedOnchainSignature) ProtoReflect() protoreflect.Message { - mi := &file_loop_internal_pb_relayer_proto_msgTypes[41] + mi := &file_loop_internal_pb_relayer_proto_msgTypes[42] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2166,7 +2226,7 @@ func (x *AttributedOnchainSignature) ProtoReflect() protoreflect.Message { // Deprecated: Use AttributedOnchainSignature.ProtoReflect.Descriptor instead. func (*AttributedOnchainSignature) Descriptor() ([]byte, []int) { - return file_loop_internal_pb_relayer_proto_rawDescGZIP(), []int{41} + return file_loop_internal_pb_relayer_proto_rawDescGZIP(), []int{42} } func (x *AttributedOnchainSignature) GetSignature() []byte { @@ -2195,7 +2255,7 @@ type TransmitRequest struct { func (x *TransmitRequest) Reset() { *x = TransmitRequest{} - mi := &file_loop_internal_pb_relayer_proto_msgTypes[42] + mi := &file_loop_internal_pb_relayer_proto_msgTypes[43] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2207,7 +2267,7 @@ func (x *TransmitRequest) String() string { func (*TransmitRequest) ProtoMessage() {} func (x *TransmitRequest) ProtoReflect() protoreflect.Message { - mi := &file_loop_internal_pb_relayer_proto_msgTypes[42] + mi := &file_loop_internal_pb_relayer_proto_msgTypes[43] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2220,7 +2280,7 @@ func (x *TransmitRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use TransmitRequest.ProtoReflect.Descriptor instead. func (*TransmitRequest) Descriptor() ([]byte, []int) { - return file_loop_internal_pb_relayer_proto_rawDescGZIP(), []int{42} + return file_loop_internal_pb_relayer_proto_rawDescGZIP(), []int{43} } func (x *TransmitRequest) GetReportContext() *ReportContext { @@ -2252,7 +2312,7 @@ type TransmitReply struct { func (x *TransmitReply) Reset() { *x = TransmitReply{} - mi := &file_loop_internal_pb_relayer_proto_msgTypes[43] + mi := &file_loop_internal_pb_relayer_proto_msgTypes[44] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2264,7 +2324,7 @@ func (x *TransmitReply) String() string { func (*TransmitReply) ProtoMessage() {} func (x *TransmitReply) ProtoReflect() protoreflect.Message { - mi := &file_loop_internal_pb_relayer_proto_msgTypes[43] + mi := &file_loop_internal_pb_relayer_proto_msgTypes[44] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2277,7 +2337,7 @@ func (x *TransmitReply) ProtoReflect() protoreflect.Message { // Deprecated: Use TransmitReply.ProtoReflect.Descriptor instead. func (*TransmitReply) Descriptor() ([]byte, []int) { - return file_loop_internal_pb_relayer_proto_rawDescGZIP(), []int{43} + return file_loop_internal_pb_relayer_proto_rawDescGZIP(), []int{44} } type LatestConfigDigestAndEpochRequest struct { @@ -2288,7 +2348,7 @@ type LatestConfigDigestAndEpochRequest struct { func (x *LatestConfigDigestAndEpochRequest) Reset() { *x = LatestConfigDigestAndEpochRequest{} - mi := &file_loop_internal_pb_relayer_proto_msgTypes[44] + mi := &file_loop_internal_pb_relayer_proto_msgTypes[45] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2300,7 +2360,7 @@ func (x *LatestConfigDigestAndEpochRequest) String() string { func (*LatestConfigDigestAndEpochRequest) ProtoMessage() {} func (x *LatestConfigDigestAndEpochRequest) ProtoReflect() protoreflect.Message { - mi := &file_loop_internal_pb_relayer_proto_msgTypes[44] + mi := &file_loop_internal_pb_relayer_proto_msgTypes[45] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2313,7 +2373,7 @@ func (x *LatestConfigDigestAndEpochRequest) ProtoReflect() protoreflect.Message // Deprecated: Use LatestConfigDigestAndEpochRequest.ProtoReflect.Descriptor instead. func (*LatestConfigDigestAndEpochRequest) Descriptor() ([]byte, []int) { - return file_loop_internal_pb_relayer_proto_rawDescGZIP(), []int{44} + return file_loop_internal_pb_relayer_proto_rawDescGZIP(), []int{45} } // LatestConfigDigestAndEpochReply has return arguments for [github.com/smartcontractkit/libocr/offchainreporting2plus/types.ContractTransmitter.LatestConfigDigestAndEpoch]. @@ -2327,7 +2387,7 @@ type LatestConfigDigestAndEpochReply struct { func (x *LatestConfigDigestAndEpochReply) Reset() { *x = LatestConfigDigestAndEpochReply{} - mi := &file_loop_internal_pb_relayer_proto_msgTypes[45] + mi := &file_loop_internal_pb_relayer_proto_msgTypes[46] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2339,7 +2399,7 @@ func (x *LatestConfigDigestAndEpochReply) String() string { func (*LatestConfigDigestAndEpochReply) ProtoMessage() {} func (x *LatestConfigDigestAndEpochReply) ProtoReflect() protoreflect.Message { - mi := &file_loop_internal_pb_relayer_proto_msgTypes[45] + mi := &file_loop_internal_pb_relayer_proto_msgTypes[46] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2352,7 +2412,7 @@ func (x *LatestConfigDigestAndEpochReply) ProtoReflect() protoreflect.Message { // Deprecated: Use LatestConfigDigestAndEpochReply.ProtoReflect.Descriptor instead. func (*LatestConfigDigestAndEpochReply) Descriptor() ([]byte, []int) { - return file_loop_internal_pb_relayer_proto_rawDescGZIP(), []int{45} + return file_loop_internal_pb_relayer_proto_rawDescGZIP(), []int{46} } func (x *LatestConfigDigestAndEpochReply) GetConfigDigest() []byte { @@ -2377,7 +2437,7 @@ type FromAccountRequest struct { func (x *FromAccountRequest) Reset() { *x = FromAccountRequest{} - mi := &file_loop_internal_pb_relayer_proto_msgTypes[46] + mi := &file_loop_internal_pb_relayer_proto_msgTypes[47] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2389,7 +2449,7 @@ func (x *FromAccountRequest) String() string { func (*FromAccountRequest) ProtoMessage() {} func (x *FromAccountRequest) ProtoReflect() protoreflect.Message { - mi := &file_loop_internal_pb_relayer_proto_msgTypes[46] + mi := &file_loop_internal_pb_relayer_proto_msgTypes[47] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2402,7 +2462,7 @@ func (x *FromAccountRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use FromAccountRequest.ProtoReflect.Descriptor instead. func (*FromAccountRequest) Descriptor() ([]byte, []int) { - return file_loop_internal_pb_relayer_proto_rawDescGZIP(), []int{46} + return file_loop_internal_pb_relayer_proto_rawDescGZIP(), []int{47} } // FromAccountReply has return arguments for [github.com/smartcontractkit/chainlink-common/pkg/types.Service.FromAccount]. @@ -2415,7 +2475,7 @@ type FromAccountReply struct { func (x *FromAccountReply) Reset() { *x = FromAccountReply{} - mi := &file_loop_internal_pb_relayer_proto_msgTypes[47] + mi := &file_loop_internal_pb_relayer_proto_msgTypes[48] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2427,7 +2487,7 @@ func (x *FromAccountReply) String() string { func (*FromAccountReply) ProtoMessage() {} func (x *FromAccountReply) ProtoReflect() protoreflect.Message { - mi := &file_loop_internal_pb_relayer_proto_msgTypes[47] + mi := &file_loop_internal_pb_relayer_proto_msgTypes[48] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2440,7 +2500,7 @@ func (x *FromAccountReply) ProtoReflect() protoreflect.Message { // Deprecated: Use FromAccountReply.ProtoReflect.Descriptor instead. func (*FromAccountReply) Descriptor() ([]byte, []int) { - return file_loop_internal_pb_relayer_proto_rawDescGZIP(), []int{47} + return file_loop_internal_pb_relayer_proto_rawDescGZIP(), []int{48} } func (x *FromAccountReply) GetAccount() string { @@ -2460,7 +2520,7 @@ type NameReply struct { func (x *NameReply) Reset() { *x = NameReply{} - mi := &file_loop_internal_pb_relayer_proto_msgTypes[48] + mi := &file_loop_internal_pb_relayer_proto_msgTypes[49] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2472,7 +2532,7 @@ func (x *NameReply) String() string { func (*NameReply) ProtoMessage() {} func (x *NameReply) ProtoReflect() protoreflect.Message { - mi := &file_loop_internal_pb_relayer_proto_msgTypes[48] + mi := &file_loop_internal_pb_relayer_proto_msgTypes[49] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2485,7 +2545,7 @@ func (x *NameReply) ProtoReflect() protoreflect.Message { // Deprecated: Use NameReply.ProtoReflect.Descriptor instead. func (*NameReply) Descriptor() ([]byte, []int) { - return file_loop_internal_pb_relayer_proto_rawDescGZIP(), []int{48} + return file_loop_internal_pb_relayer_proto_rawDescGZIP(), []int{49} } func (x *NameReply) GetName() string { @@ -2505,7 +2565,7 @@ type HealthReportReply struct { func (x *HealthReportReply) Reset() { *x = HealthReportReply{} - mi := &file_loop_internal_pb_relayer_proto_msgTypes[49] + mi := &file_loop_internal_pb_relayer_proto_msgTypes[50] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2517,7 +2577,7 @@ func (x *HealthReportReply) String() string { func (*HealthReportReply) ProtoMessage() {} func (x *HealthReportReply) ProtoReflect() protoreflect.Message { - mi := &file_loop_internal_pb_relayer_proto_msgTypes[49] + mi := &file_loop_internal_pb_relayer_proto_msgTypes[50] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2530,7 +2590,7 @@ func (x *HealthReportReply) ProtoReflect() protoreflect.Message { // Deprecated: Use HealthReportReply.ProtoReflect.Descriptor instead. func (*HealthReportReply) Descriptor() ([]byte, []int) { - return file_loop_internal_pb_relayer_proto_rawDescGZIP(), []int{49} + return file_loop_internal_pb_relayer_proto_rawDescGZIP(), []int{50} } func (x *HealthReportReply) GetHealthReport() map[string]string { @@ -2551,7 +2611,7 @@ type BigInt struct { func (x *BigInt) Reset() { *x = BigInt{} - mi := &file_loop_internal_pb_relayer_proto_msgTypes[50] + mi := &file_loop_internal_pb_relayer_proto_msgTypes[51] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2563,7 +2623,7 @@ func (x *BigInt) String() string { func (*BigInt) ProtoMessage() {} func (x *BigInt) ProtoReflect() protoreflect.Message { - mi := &file_loop_internal_pb_relayer_proto_msgTypes[50] + mi := &file_loop_internal_pb_relayer_proto_msgTypes[51] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2576,7 +2636,7 @@ func (x *BigInt) ProtoReflect() protoreflect.Message { // Deprecated: Use BigInt.ProtoReflect.Descriptor instead. func (*BigInt) Descriptor() ([]byte, []int) { - return file_loop_internal_pb_relayer_proto_rawDescGZIP(), []int{50} + return file_loop_internal_pb_relayer_proto_rawDescGZIP(), []int{51} } func (x *BigInt) GetNegative() bool { @@ -2603,7 +2663,7 @@ type StarknetSignature struct { func (x *StarknetSignature) Reset() { *x = StarknetSignature{} - mi := &file_loop_internal_pb_relayer_proto_msgTypes[51] + mi := &file_loop_internal_pb_relayer_proto_msgTypes[52] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2615,7 +2675,7 @@ func (x *StarknetSignature) String() string { func (*StarknetSignature) ProtoMessage() {} func (x *StarknetSignature) ProtoReflect() protoreflect.Message { - mi := &file_loop_internal_pb_relayer_proto_msgTypes[51] + mi := &file_loop_internal_pb_relayer_proto_msgTypes[52] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2628,7 +2688,7 @@ func (x *StarknetSignature) ProtoReflect() protoreflect.Message { // Deprecated: Use StarknetSignature.ProtoReflect.Descriptor instead. func (*StarknetSignature) Descriptor() ([]byte, []int) { - return file_loop_internal_pb_relayer_proto_rawDescGZIP(), []int{51} + return file_loop_internal_pb_relayer_proto_rawDescGZIP(), []int{52} } func (x *StarknetSignature) GetX() *BigInt { @@ -2654,7 +2714,7 @@ type StarknetMessageHash struct { func (x *StarknetMessageHash) Reset() { *x = StarknetMessageHash{} - mi := &file_loop_internal_pb_relayer_proto_msgTypes[52] + mi := &file_loop_internal_pb_relayer_proto_msgTypes[53] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2666,7 +2726,7 @@ func (x *StarknetMessageHash) String() string { func (*StarknetMessageHash) ProtoMessage() {} func (x *StarknetMessageHash) ProtoReflect() protoreflect.Message { - mi := &file_loop_internal_pb_relayer_proto_msgTypes[52] + mi := &file_loop_internal_pb_relayer_proto_msgTypes[53] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2679,7 +2739,7 @@ func (x *StarknetMessageHash) ProtoReflect() protoreflect.Message { // Deprecated: Use StarknetMessageHash.ProtoReflect.Descriptor instead. func (*StarknetMessageHash) Descriptor() ([]byte, []int) { - return file_loop_internal_pb_relayer_proto_rawDescGZIP(), []int{52} + return file_loop_internal_pb_relayer_proto_rawDescGZIP(), []int{53} } func (x *StarknetMessageHash) GetHash() *BigInt { @@ -2715,7 +2775,7 @@ const file_loop_internal_pb_relayer_proto_rawDesc = "" + "\n" + "PluginArgs\x12$\n" + "\rtransmitterID\x18\x01 \x01(\tR\rtransmitterID\x12\"\n" + - "\fpluginConfig\x18\x02 \x01(\fR\fpluginConfig\"\xe2\x01\n" + + "\fpluginConfig\x18\x02 \x01(\fR\fpluginConfig\"\xa0\x02\n" + "\x10CCIPProviderArgs\x12$\n" + "\rexternalJobID\x18\x01 \x01(\fR\rexternalJobID\x122\n" + "\x14contractReaderConfig\x18\x02 \x01(\fR\x14contractReaderConfig\x12,\n" + @@ -2723,7 +2783,11 @@ const file_loop_internal_pb_relayer_proto_rawDesc = "" + "\x0eOffRampAddress\x18\x04 \x01(\tR\x0eOffRampAddress\x12\x1e\n" + "\n" + "pluginType\x18\x05 \x01(\rR\n" + - "pluginType\"N\n" + + "pluginType\x12<\n" + + "\x0fsyncedContracts\x18\x06 \x03(\v2\x12.loop.SyncContractR\x0fsyncedContracts\"\\\n" + + "\fSyncContract\x12\"\n" + + "\fcontractName\x18\x01 \x01(\tR\fcontractName\x12(\n" + + "\x0fcontractAddress\x18\x02 \x01(\fR\x0fcontractAddress\"N\n" + "\x18NewContractWriterRequest\x122\n" + "\x14contractWriterConfig\x18\x01 \x01(\fR\x14contractWriterConfig\"D\n" + "\x16NewContractWriterReply\x12*\n" + @@ -2899,139 +2963,141 @@ func file_loop_internal_pb_relayer_proto_rawDescGZIP() []byte { return file_loop_internal_pb_relayer_proto_rawDescData } -var file_loop_internal_pb_relayer_proto_msgTypes = make([]protoimpl.MessageInfo, 54) +var file_loop_internal_pb_relayer_proto_msgTypes = make([]protoimpl.MessageInfo, 55) var file_loop_internal_pb_relayer_proto_goTypes = []any{ (*NewRelayerRequest)(nil), // 0: loop.NewRelayerRequest (*NewRelayerReply)(nil), // 1: loop.NewRelayerReply (*RelayArgs)(nil), // 2: loop.RelayArgs (*PluginArgs)(nil), // 3: loop.PluginArgs (*CCIPProviderArgs)(nil), // 4: loop.CCIPProviderArgs - (*NewContractWriterRequest)(nil), // 5: loop.NewContractWriterRequest - (*NewContractWriterReply)(nil), // 6: loop.NewContractWriterReply - (*NewContractReaderRequest)(nil), // 7: loop.NewContractReaderRequest - (*NewContractReaderReply)(nil), // 8: loop.NewContractReaderReply - (*NewPluginProviderRequest)(nil), // 9: loop.NewPluginProviderRequest - (*NewPluginProviderReply)(nil), // 10: loop.NewPluginProviderReply - (*NewConfigProviderRequest)(nil), // 11: loop.NewConfigProviderRequest - (*NewConfigProviderReply)(nil), // 12: loop.NewConfigProviderReply - (*NewCCIPProviderRequest)(nil), // 13: loop.NewCCIPProviderRequest - (*NewCCIPProviderReply)(nil), // 14: loop.NewCCIPProviderReply - (*LatestHeadRequest)(nil), // 15: loop.LatestHeadRequest - (*LatestHeadReply)(nil), // 16: loop.LatestHeadReply - (*GetChainStatusRequest)(nil), // 17: loop.GetChainStatusRequest - (*GetChainStatusReply)(nil), // 18: loop.GetChainStatusReply - (*GetChainInfoRequest)(nil), // 19: loop.GetChainInfoRequest - (*GetChainInfoReply)(nil), // 20: loop.GetChainInfoReply - (*ChainStatus)(nil), // 21: loop.ChainStatus - (*ChainInfo)(nil), // 22: loop.ChainInfo - (*ListNodeStatusesRequest)(nil), // 23: loop.ListNodeStatusesRequest - (*ListNodeStatusesReply)(nil), // 24: loop.ListNodeStatusesReply - (*NodeStatus)(nil), // 25: loop.NodeStatus - (*ReplayRequest)(nil), // 26: loop.ReplayRequest - (*TransactionRequest)(nil), // 27: loop.TransactionRequest - (*ContractConfig)(nil), // 28: loop.ContractConfig - (*ConfigDigestRequest)(nil), // 29: loop.ConfigDigestRequest - (*ConfigDigestReply)(nil), // 30: loop.ConfigDigestReply - (*ConfigDigestPrefixRequest)(nil), // 31: loop.ConfigDigestPrefixRequest - (*ConfigDigestPrefixReply)(nil), // 32: loop.ConfigDigestPrefixReply - (*LatestConfigDetailsRequest)(nil), // 33: loop.LatestConfigDetailsRequest - (*LatestConfigDetailsReply)(nil), // 34: loop.LatestConfigDetailsReply - (*LatestConfigRequest)(nil), // 35: loop.LatestConfigRequest - (*LatestConfigReply)(nil), // 36: loop.LatestConfigReply - (*LatestBlockHeightRequest)(nil), // 37: loop.LatestBlockHeightRequest - (*LatestBlockHeightReply)(nil), // 38: loop.LatestBlockHeightReply - (*ReportTimestamp)(nil), // 39: loop.ReportTimestamp - (*ReportContext)(nil), // 40: loop.ReportContext - (*AttributedOnchainSignature)(nil), // 41: loop.AttributedOnchainSignature - (*TransmitRequest)(nil), // 42: loop.TransmitRequest - (*TransmitReply)(nil), // 43: loop.TransmitReply - (*LatestConfigDigestAndEpochRequest)(nil), // 44: loop.LatestConfigDigestAndEpochRequest - (*LatestConfigDigestAndEpochReply)(nil), // 45: loop.LatestConfigDigestAndEpochReply - (*FromAccountRequest)(nil), // 46: loop.FromAccountRequest - (*FromAccountReply)(nil), // 47: loop.FromAccountReply - (*NameReply)(nil), // 48: loop.NameReply - (*HealthReportReply)(nil), // 49: loop.HealthReportReply - (*BigInt)(nil), // 50: loop.BigInt - (*StarknetSignature)(nil), // 51: loop.StarknetSignature - (*StarknetMessageHash)(nil), // 52: loop.StarknetMessageHash - nil, // 53: loop.HealthReportReply.HealthReportEntry - (*Head)(nil), // 54: loop.Head - (*structpb.Struct)(nil), // 55: google.protobuf.Struct - (*emptypb.Empty)(nil), // 56: google.protobuf.Empty + (*SyncContract)(nil), // 5: loop.SyncContract + (*NewContractWriterRequest)(nil), // 6: loop.NewContractWriterRequest + (*NewContractWriterReply)(nil), // 7: loop.NewContractWriterReply + (*NewContractReaderRequest)(nil), // 8: loop.NewContractReaderRequest + (*NewContractReaderReply)(nil), // 9: loop.NewContractReaderReply + (*NewPluginProviderRequest)(nil), // 10: loop.NewPluginProviderRequest + (*NewPluginProviderReply)(nil), // 11: loop.NewPluginProviderReply + (*NewConfigProviderRequest)(nil), // 12: loop.NewConfigProviderRequest + (*NewConfigProviderReply)(nil), // 13: loop.NewConfigProviderReply + (*NewCCIPProviderRequest)(nil), // 14: loop.NewCCIPProviderRequest + (*NewCCIPProviderReply)(nil), // 15: loop.NewCCIPProviderReply + (*LatestHeadRequest)(nil), // 16: loop.LatestHeadRequest + (*LatestHeadReply)(nil), // 17: loop.LatestHeadReply + (*GetChainStatusRequest)(nil), // 18: loop.GetChainStatusRequest + (*GetChainStatusReply)(nil), // 19: loop.GetChainStatusReply + (*GetChainInfoRequest)(nil), // 20: loop.GetChainInfoRequest + (*GetChainInfoReply)(nil), // 21: loop.GetChainInfoReply + (*ChainStatus)(nil), // 22: loop.ChainStatus + (*ChainInfo)(nil), // 23: loop.ChainInfo + (*ListNodeStatusesRequest)(nil), // 24: loop.ListNodeStatusesRequest + (*ListNodeStatusesReply)(nil), // 25: loop.ListNodeStatusesReply + (*NodeStatus)(nil), // 26: loop.NodeStatus + (*ReplayRequest)(nil), // 27: loop.ReplayRequest + (*TransactionRequest)(nil), // 28: loop.TransactionRequest + (*ContractConfig)(nil), // 29: loop.ContractConfig + (*ConfigDigestRequest)(nil), // 30: loop.ConfigDigestRequest + (*ConfigDigestReply)(nil), // 31: loop.ConfigDigestReply + (*ConfigDigestPrefixRequest)(nil), // 32: loop.ConfigDigestPrefixRequest + (*ConfigDigestPrefixReply)(nil), // 33: loop.ConfigDigestPrefixReply + (*LatestConfigDetailsRequest)(nil), // 34: loop.LatestConfigDetailsRequest + (*LatestConfigDetailsReply)(nil), // 35: loop.LatestConfigDetailsReply + (*LatestConfigRequest)(nil), // 36: loop.LatestConfigRequest + (*LatestConfigReply)(nil), // 37: loop.LatestConfigReply + (*LatestBlockHeightRequest)(nil), // 38: loop.LatestBlockHeightRequest + (*LatestBlockHeightReply)(nil), // 39: loop.LatestBlockHeightReply + (*ReportTimestamp)(nil), // 40: loop.ReportTimestamp + (*ReportContext)(nil), // 41: loop.ReportContext + (*AttributedOnchainSignature)(nil), // 42: loop.AttributedOnchainSignature + (*TransmitRequest)(nil), // 43: loop.TransmitRequest + (*TransmitReply)(nil), // 44: loop.TransmitReply + (*LatestConfigDigestAndEpochRequest)(nil), // 45: loop.LatestConfigDigestAndEpochRequest + (*LatestConfigDigestAndEpochReply)(nil), // 46: loop.LatestConfigDigestAndEpochReply + (*FromAccountRequest)(nil), // 47: loop.FromAccountRequest + (*FromAccountReply)(nil), // 48: loop.FromAccountReply + (*NameReply)(nil), // 49: loop.NameReply + (*HealthReportReply)(nil), // 50: loop.HealthReportReply + (*BigInt)(nil), // 51: loop.BigInt + (*StarknetSignature)(nil), // 52: loop.StarknetSignature + (*StarknetMessageHash)(nil), // 53: loop.StarknetMessageHash + nil, // 54: loop.HealthReportReply.HealthReportEntry + (*Head)(nil), // 55: loop.Head + (*structpb.Struct)(nil), // 56: google.protobuf.Struct + (*emptypb.Empty)(nil), // 57: google.protobuf.Empty } var file_loop_internal_pb_relayer_proto_depIdxs = []int32{ - 2, // 0: loop.NewPluginProviderRequest.relayArgs:type_name -> loop.RelayArgs - 3, // 1: loop.NewPluginProviderRequest.pluginArgs:type_name -> loop.PluginArgs - 2, // 2: loop.NewConfigProviderRequest.relayArgs:type_name -> loop.RelayArgs - 4, // 3: loop.NewCCIPProviderRequest.ccipProviderArgs:type_name -> loop.CCIPProviderArgs - 54, // 4: loop.LatestHeadReply.head:type_name -> loop.Head - 21, // 5: loop.GetChainStatusReply.chain:type_name -> loop.ChainStatus - 22, // 6: loop.GetChainInfoReply.chain_info:type_name -> loop.ChainInfo - 25, // 7: loop.ListNodeStatusesReply.nodes:type_name -> loop.NodeStatus - 55, // 8: loop.ReplayRequest.args:type_name -> google.protobuf.Struct - 50, // 9: loop.TransactionRequest.amount:type_name -> loop.BigInt - 28, // 10: loop.ConfigDigestRequest.contractConfig:type_name -> loop.ContractConfig - 28, // 11: loop.LatestConfigReply.contractConfig:type_name -> loop.ContractConfig - 39, // 12: loop.ReportContext.reportTimestamp:type_name -> loop.ReportTimestamp - 40, // 13: loop.TransmitRequest.reportContext:type_name -> loop.ReportContext - 41, // 14: loop.TransmitRequest.attributedOnchainSignatures:type_name -> loop.AttributedOnchainSignature - 53, // 15: loop.HealthReportReply.healthReport:type_name -> loop.HealthReportReply.HealthReportEntry - 50, // 16: loop.StarknetSignature.x:type_name -> loop.BigInt - 50, // 17: loop.StarknetSignature.y:type_name -> loop.BigInt - 50, // 18: loop.StarknetMessageHash.hash:type_name -> loop.BigInt - 0, // 19: loop.PluginRelayer.NewRelayer:input_type -> loop.NewRelayerRequest - 5, // 20: loop.Relayer.NewContractWriter:input_type -> loop.NewContractWriterRequest - 7, // 21: loop.Relayer.NewContractReader:input_type -> loop.NewContractReaderRequest - 11, // 22: loop.Relayer.NewConfigProvider:input_type -> loop.NewConfigProviderRequest - 9, // 23: loop.Relayer.NewPluginProvider:input_type -> loop.NewPluginProviderRequest - 13, // 24: loop.Relayer.NewCCIPProvider:input_type -> loop.NewCCIPProviderRequest - 15, // 25: loop.Relayer.LatestHead:input_type -> loop.LatestHeadRequest - 17, // 26: loop.Relayer.GetChainStatus:input_type -> loop.GetChainStatusRequest - 19, // 27: loop.Relayer.GetChainInfo:input_type -> loop.GetChainInfoRequest - 23, // 28: loop.Relayer.ListNodeStatuses:input_type -> loop.ListNodeStatusesRequest - 27, // 29: loop.Relayer.Transact:input_type -> loop.TransactionRequest - 26, // 30: loop.Relayer.Replay:input_type -> loop.ReplayRequest - 29, // 31: loop.OffchainConfigDigester.ConfigDigest:input_type -> loop.ConfigDigestRequest - 31, // 32: loop.OffchainConfigDigester.ConfigDigestPrefix:input_type -> loop.ConfigDigestPrefixRequest - 33, // 33: loop.ContractConfigTracker.LatestConfigDetails:input_type -> loop.LatestConfigDetailsRequest - 35, // 34: loop.ContractConfigTracker.LatestConfig:input_type -> loop.LatestConfigRequest - 37, // 35: loop.ContractConfigTracker.LatestBlockHeight:input_type -> loop.LatestBlockHeightRequest - 42, // 36: loop.ContractTransmitter.Transmit:input_type -> loop.TransmitRequest - 44, // 37: loop.ContractTransmitter.LatestConfigDigestAndEpoch:input_type -> loop.LatestConfigDigestAndEpochRequest - 46, // 38: loop.ContractTransmitter.FromAccount:input_type -> loop.FromAccountRequest - 56, // 39: loop.Service.Name:input_type -> google.protobuf.Empty - 56, // 40: loop.Service.Close:input_type -> google.protobuf.Empty - 56, // 41: loop.Service.Ready:input_type -> google.protobuf.Empty - 56, // 42: loop.Service.HealthReport:input_type -> google.protobuf.Empty - 1, // 43: loop.PluginRelayer.NewRelayer:output_type -> loop.NewRelayerReply - 6, // 44: loop.Relayer.NewContractWriter:output_type -> loop.NewContractWriterReply - 8, // 45: loop.Relayer.NewContractReader:output_type -> loop.NewContractReaderReply - 12, // 46: loop.Relayer.NewConfigProvider:output_type -> loop.NewConfigProviderReply - 10, // 47: loop.Relayer.NewPluginProvider:output_type -> loop.NewPluginProviderReply - 14, // 48: loop.Relayer.NewCCIPProvider:output_type -> loop.NewCCIPProviderReply - 16, // 49: loop.Relayer.LatestHead:output_type -> loop.LatestHeadReply - 18, // 50: loop.Relayer.GetChainStatus:output_type -> loop.GetChainStatusReply - 20, // 51: loop.Relayer.GetChainInfo:output_type -> loop.GetChainInfoReply - 24, // 52: loop.Relayer.ListNodeStatuses:output_type -> loop.ListNodeStatusesReply - 56, // 53: loop.Relayer.Transact:output_type -> google.protobuf.Empty - 56, // 54: loop.Relayer.Replay:output_type -> google.protobuf.Empty - 30, // 55: loop.OffchainConfigDigester.ConfigDigest:output_type -> loop.ConfigDigestReply - 32, // 56: loop.OffchainConfigDigester.ConfigDigestPrefix:output_type -> loop.ConfigDigestPrefixReply - 34, // 57: loop.ContractConfigTracker.LatestConfigDetails:output_type -> loop.LatestConfigDetailsReply - 36, // 58: loop.ContractConfigTracker.LatestConfig:output_type -> loop.LatestConfigReply - 38, // 59: loop.ContractConfigTracker.LatestBlockHeight:output_type -> loop.LatestBlockHeightReply - 43, // 60: loop.ContractTransmitter.Transmit:output_type -> loop.TransmitReply - 45, // 61: loop.ContractTransmitter.LatestConfigDigestAndEpoch:output_type -> loop.LatestConfigDigestAndEpochReply - 47, // 62: loop.ContractTransmitter.FromAccount:output_type -> loop.FromAccountReply - 48, // 63: loop.Service.Name:output_type -> loop.NameReply - 56, // 64: loop.Service.Close:output_type -> google.protobuf.Empty - 56, // 65: loop.Service.Ready:output_type -> google.protobuf.Empty - 49, // 66: loop.Service.HealthReport:output_type -> loop.HealthReportReply - 43, // [43:67] is the sub-list for method output_type - 19, // [19:43] is the sub-list for method input_type - 19, // [19:19] is the sub-list for extension type_name - 19, // [19:19] is the sub-list for extension extendee - 0, // [0:19] is the sub-list for field type_name + 5, // 0: loop.CCIPProviderArgs.syncedContracts:type_name -> loop.SyncContract + 2, // 1: loop.NewPluginProviderRequest.relayArgs:type_name -> loop.RelayArgs + 3, // 2: loop.NewPluginProviderRequest.pluginArgs:type_name -> loop.PluginArgs + 2, // 3: loop.NewConfigProviderRequest.relayArgs:type_name -> loop.RelayArgs + 4, // 4: loop.NewCCIPProviderRequest.ccipProviderArgs:type_name -> loop.CCIPProviderArgs + 55, // 5: loop.LatestHeadReply.head:type_name -> loop.Head + 22, // 6: loop.GetChainStatusReply.chain:type_name -> loop.ChainStatus + 23, // 7: loop.GetChainInfoReply.chain_info:type_name -> loop.ChainInfo + 26, // 8: loop.ListNodeStatusesReply.nodes:type_name -> loop.NodeStatus + 56, // 9: loop.ReplayRequest.args:type_name -> google.protobuf.Struct + 51, // 10: loop.TransactionRequest.amount:type_name -> loop.BigInt + 29, // 11: loop.ConfigDigestRequest.contractConfig:type_name -> loop.ContractConfig + 29, // 12: loop.LatestConfigReply.contractConfig:type_name -> loop.ContractConfig + 40, // 13: loop.ReportContext.reportTimestamp:type_name -> loop.ReportTimestamp + 41, // 14: loop.TransmitRequest.reportContext:type_name -> loop.ReportContext + 42, // 15: loop.TransmitRequest.attributedOnchainSignatures:type_name -> loop.AttributedOnchainSignature + 54, // 16: loop.HealthReportReply.healthReport:type_name -> loop.HealthReportReply.HealthReportEntry + 51, // 17: loop.StarknetSignature.x:type_name -> loop.BigInt + 51, // 18: loop.StarknetSignature.y:type_name -> loop.BigInt + 51, // 19: loop.StarknetMessageHash.hash:type_name -> loop.BigInt + 0, // 20: loop.PluginRelayer.NewRelayer:input_type -> loop.NewRelayerRequest + 6, // 21: loop.Relayer.NewContractWriter:input_type -> loop.NewContractWriterRequest + 8, // 22: loop.Relayer.NewContractReader:input_type -> loop.NewContractReaderRequest + 12, // 23: loop.Relayer.NewConfigProvider:input_type -> loop.NewConfigProviderRequest + 10, // 24: loop.Relayer.NewPluginProvider:input_type -> loop.NewPluginProviderRequest + 14, // 25: loop.Relayer.NewCCIPProvider:input_type -> loop.NewCCIPProviderRequest + 16, // 26: loop.Relayer.LatestHead:input_type -> loop.LatestHeadRequest + 18, // 27: loop.Relayer.GetChainStatus:input_type -> loop.GetChainStatusRequest + 20, // 28: loop.Relayer.GetChainInfo:input_type -> loop.GetChainInfoRequest + 24, // 29: loop.Relayer.ListNodeStatuses:input_type -> loop.ListNodeStatusesRequest + 28, // 30: loop.Relayer.Transact:input_type -> loop.TransactionRequest + 27, // 31: loop.Relayer.Replay:input_type -> loop.ReplayRequest + 30, // 32: loop.OffchainConfigDigester.ConfigDigest:input_type -> loop.ConfigDigestRequest + 32, // 33: loop.OffchainConfigDigester.ConfigDigestPrefix:input_type -> loop.ConfigDigestPrefixRequest + 34, // 34: loop.ContractConfigTracker.LatestConfigDetails:input_type -> loop.LatestConfigDetailsRequest + 36, // 35: loop.ContractConfigTracker.LatestConfig:input_type -> loop.LatestConfigRequest + 38, // 36: loop.ContractConfigTracker.LatestBlockHeight:input_type -> loop.LatestBlockHeightRequest + 43, // 37: loop.ContractTransmitter.Transmit:input_type -> loop.TransmitRequest + 45, // 38: loop.ContractTransmitter.LatestConfigDigestAndEpoch:input_type -> loop.LatestConfigDigestAndEpochRequest + 47, // 39: loop.ContractTransmitter.FromAccount:input_type -> loop.FromAccountRequest + 57, // 40: loop.Service.Name:input_type -> google.protobuf.Empty + 57, // 41: loop.Service.Close:input_type -> google.protobuf.Empty + 57, // 42: loop.Service.Ready:input_type -> google.protobuf.Empty + 57, // 43: loop.Service.HealthReport:input_type -> google.protobuf.Empty + 1, // 44: loop.PluginRelayer.NewRelayer:output_type -> loop.NewRelayerReply + 7, // 45: loop.Relayer.NewContractWriter:output_type -> loop.NewContractWriterReply + 9, // 46: loop.Relayer.NewContractReader:output_type -> loop.NewContractReaderReply + 13, // 47: loop.Relayer.NewConfigProvider:output_type -> loop.NewConfigProviderReply + 11, // 48: loop.Relayer.NewPluginProvider:output_type -> loop.NewPluginProviderReply + 15, // 49: loop.Relayer.NewCCIPProvider:output_type -> loop.NewCCIPProviderReply + 17, // 50: loop.Relayer.LatestHead:output_type -> loop.LatestHeadReply + 19, // 51: loop.Relayer.GetChainStatus:output_type -> loop.GetChainStatusReply + 21, // 52: loop.Relayer.GetChainInfo:output_type -> loop.GetChainInfoReply + 25, // 53: loop.Relayer.ListNodeStatuses:output_type -> loop.ListNodeStatusesReply + 57, // 54: loop.Relayer.Transact:output_type -> google.protobuf.Empty + 57, // 55: loop.Relayer.Replay:output_type -> google.protobuf.Empty + 31, // 56: loop.OffchainConfigDigester.ConfigDigest:output_type -> loop.ConfigDigestReply + 33, // 57: loop.OffchainConfigDigester.ConfigDigestPrefix:output_type -> loop.ConfigDigestPrefixReply + 35, // 58: loop.ContractConfigTracker.LatestConfigDetails:output_type -> loop.LatestConfigDetailsReply + 37, // 59: loop.ContractConfigTracker.LatestConfig:output_type -> loop.LatestConfigReply + 39, // 60: loop.ContractConfigTracker.LatestBlockHeight:output_type -> loop.LatestBlockHeightReply + 44, // 61: loop.ContractTransmitter.Transmit:output_type -> loop.TransmitReply + 46, // 62: loop.ContractTransmitter.LatestConfigDigestAndEpoch:output_type -> loop.LatestConfigDigestAndEpochReply + 48, // 63: loop.ContractTransmitter.FromAccount:output_type -> loop.FromAccountReply + 49, // 64: loop.Service.Name:output_type -> loop.NameReply + 57, // 65: loop.Service.Close:output_type -> google.protobuf.Empty + 57, // 66: loop.Service.Ready:output_type -> google.protobuf.Empty + 50, // 67: loop.Service.HealthReport:output_type -> loop.HealthReportReply + 44, // [44:68] is the sub-list for method output_type + 20, // [20:44] is the sub-list for method input_type + 20, // [20:20] is the sub-list for extension type_name + 20, // [20:20] is the sub-list for extension extendee + 0, // [0:20] is the sub-list for field type_name } func init() { file_loop_internal_pb_relayer_proto_init() } @@ -3046,7 +3112,7 @@ func file_loop_internal_pb_relayer_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: unsafe.Slice(unsafe.StringData(file_loop_internal_pb_relayer_proto_rawDesc), len(file_loop_internal_pb_relayer_proto_rawDesc)), NumEnums: 0, - NumMessages: 54, + NumMessages: 55, NumExtensions: 0, NumServices: 6, }, diff --git a/pkg/loop/internal/pb/relayer.proto b/pkg/loop/internal/pb/relayer.proto index 56c959f8d..b9a4eb570 100644 --- a/pkg/loop/internal/pb/relayer.proto +++ b/pkg/loop/internal/pb/relayer.proto @@ -62,6 +62,12 @@ message CCIPProviderArgs { bytes chainWriterConfig = 3; string OffRampAddress = 4; uint32 pluginType = 5; + repeated SyncContract syncedContracts = 6; // Previously synced contracts to restore +} + +message SyncContract { + string contractName = 1; + bytes contractAddress = 2; } // NewContractWriterRequest has request parameters for [github.com/smartcontractkit/chainlink-common/pkg/loop.Relayer.NewContractWriter]. diff --git a/pkg/loop/internal/relayer/pluginprovider/ext/ccipocr3/chainaccessor.go b/pkg/loop/internal/relayer/pluginprovider/ext/ccipocr3/chainaccessor.go index ea402484c..aa82131fb 100644 --- a/pkg/loop/internal/relayer/pluginprovider/ext/ccipocr3/chainaccessor.go +++ b/pkg/loop/internal/relayer/pluginprovider/ext/ccipocr3/chainaccessor.go @@ -2,6 +2,8 @@ package ccipocr3 import ( "context" + "fmt" + "sync" "time" "google.golang.org/grpc" @@ -19,13 +21,22 @@ var _ ccipocr3.ChainAccessor = (*chainAccessorClient)(nil) type chainAccessorClient struct { *net.BrokerExt grpc ccipocr3pb.ChainAccessorClient + + // Local persistence for refresh functionality + mu sync.RWMutex + syncedContracts map[string]ccipocr3.UnknownAddress // contractName -> contractAddress } func NewChainAccessorClient(broker *net.BrokerExt, cc grpc.ClientConnInterface) ccipocr3.ChainAccessor { - return &chainAccessorClient{ - BrokerExt: broker, - grpc: ccipocr3pb.NewChainAccessorClient(cc), + client := &chainAccessorClient{ + BrokerExt: broker, + grpc: ccipocr3pb.NewChainAccessorClient(cc), + syncedContracts: make(map[string]ccipocr3.UnknownAddress), } + + broker.SetOnRefreshComplete(client.restoreStateOnRefresh) + + return client } // AllAccessors methods @@ -82,9 +93,75 @@ func (c *chainAccessorClient) Sync(ctx context.Context, contractName string, con ContractName: contractName, ContractAddress: contractAddress, }) + + if err == nil { + // Persist the synced contract locally for client refresh + c.mu.Lock() + c.syncedContracts[contractName] = contractAddress + c.mu.Unlock() + c.Logger.Debugw("Persisted synced contract", "contractName", contractName, "contractAddress", contractAddress) + } + return err } +// GetSyncedContracts returns a copy of all previously synced contracts. +// This is used to restore contract sync state during connection refresh. +func (c *chainAccessorClient) GetSyncedContracts() map[string]ccipocr3.UnknownAddress { + c.mu.RLock() + defer c.mu.RUnlock() + + // Return a copy + contracts := make(map[string]ccipocr3.UnknownAddress) + for name, addr := range c.syncedContracts { + contracts[name] = addr + } + return contracts +} + +// restoreStateOnRefresh is called after successful relayer refresh to restore synced contracts. +// +// TODO: right now this only supports re-syncing previously synced contracts. In the future this should support +// re-establishing any arbitrary serializable state. +func (c *chainAccessorClient) restoreStateOnRefresh(ctx context.Context) error { + c.mu.RLock() + contractsToRestore := make(map[string]ccipocr3.UnknownAddress) + for name, addr := range c.syncedContracts { + contractsToRestore[name] = addr + } + c.mu.RUnlock() + + if len(contractsToRestore) == 0 { + c.Logger.Debug("No synced contracts to restore") + return nil + } + + c.Logger.Infow("Restoring synced contracts after refresh", "count", len(contractsToRestore)) + + // Re-sync all previously synced contracts + var restoreErrors []error + for contractName, contractAddress := range contractsToRestore { + if err := c.Sync(ctx, contractName, contractAddress); err != nil { + c.Logger.Errorw("Failed to restore synced contract", + "contractName", contractName, + "contractAddress", contractAddress, + "err", err) + restoreErrors = append(restoreErrors, fmt.Errorf("failed to restore contract %s: %w", contractName, err)) + } else { + c.Logger.Debugw("Successfully restored synced contract", + "contractName", contractName, + "contractAddress", contractAddress) + } + } + + if len(restoreErrors) > 0 { + return fmt.Errorf("failed to restore %d/%d contracts: %v", len(restoreErrors), len(contractsToRestore), restoreErrors) + } + + c.Logger.Infow("Successfully restored all synced contracts", "count", len(contractsToRestore)) + return nil +} + // DestinationAccessor methods func (c *chainAccessorClient) CommitReportsGTETimestamp( ctx context.Context, @@ -194,7 +271,7 @@ func (c *chainAccessorClient) Nonces(ctx context.Context, addresses map[ccipocr3 return result, nil } -func (c *chainAccessorClient) GetChainFeePriceUpdate(ctx context.Context, selectors []ccipocr3.ChainSelector) map[ccipocr3.ChainSelector]ccipocr3.TimestampedBig { +func (c *chainAccessorClient) GetChainFeePriceUpdate(ctx context.Context, selectors []ccipocr3.ChainSelector) (map[ccipocr3.ChainSelector]ccipocr3.TimestampedUnixBig, error) { var chainSelectors []uint64 for _, sel := range selectors { chainSelectors = append(chainSelectors, uint64(sel)) @@ -204,27 +281,25 @@ func (c *chainAccessorClient) GetChainFeePriceUpdate(ctx context.Context, select ChainSelectors: chainSelectors, }) if err != nil { - // This method returns a map, not error, so we need to handle errors differently - // Return empty map for now - this matches the interface signature - return make(map[ccipocr3.ChainSelector]ccipocr3.TimestampedBig) + return nil, err } - result := make(map[ccipocr3.ChainSelector]ccipocr3.TimestampedBig) - for chainSel, timestampedBig := range resp.FeePriceUpdates { - result[ccipocr3.ChainSelector(chainSel)] = ccipocr3.TimestampedBig{ - Timestamp: timestampedBig.Timestamp.AsTime(), - Value: pbToBigInt(timestampedBig.Value), + result := make(map[ccipocr3.ChainSelector]ccipocr3.TimestampedUnixBig) + for chainSel, timestampedUnixBig := range resp.FeePriceUpdates { + result[ccipocr3.ChainSelector(chainSel)] = ccipocr3.TimestampedUnixBig{ + Value: pbToBigInt(timestampedUnixBig.Value).Int, + Timestamp: timestampedUnixBig.Timestamp, } } - return result + return result, nil } -func (c *chainAccessorClient) GetLatestPriceSeqNr(ctx context.Context) (uint64, error) { +func (c *chainAccessorClient) GetLatestPriceSeqNr(ctx context.Context) (ccipocr3.SeqNum, error) { resp, err := c.grpc.GetLatestPriceSeqNr(ctx, &emptypb.Empty{}) if err != nil { return 0, err } - return resp.SeqNr, nil + return ccipocr3.SeqNum(resp.SeqNr), nil } // SourceAccessor methods @@ -290,6 +365,52 @@ func (c *chainAccessorClient) GetFeeQuoterDestChainConfig(ctx context.Context, d return pbToFeeQuoterDestChainConfigDetailed(resp.Config), nil } +// USDCMessageReader methods +func (c *chainAccessorClient) MessagesByTokenID(ctx context.Context, source, dest ccipocr3.ChainSelector, tokens map[ccipocr3.MessageTokenID]ccipocr3.RampTokenAmount) (map[ccipocr3.MessageTokenID]ccipocr3.Bytes, error) { + resp, err := c.grpc.MessagesByTokenID(ctx, &ccipocr3pb.MessagesByTokenIDRequest{ + SourceChainSelector: uint64(source), + DestChainSelector: uint64(dest), + Tokens: messageTokenIDMapToPb(tokens), + }) + if err != nil { + return nil, err + } + return pbToMessagesByTokenID(resp.Messages) +} + +// PriceReader methods +func (c *chainAccessorClient) GetFeedPricesUSD(ctx context.Context, tokens []ccipocr3.UnknownEncodedAddress, tokenInfo map[ccipocr3.UnknownEncodedAddress]ccipocr3.TokenInfo) (ccipocr3.TokenPriceMap, error) { + var tokenStrs []string + for _, token := range tokens { + tokenStrs = append(tokenStrs, string(token)) + } + + resp, err := c.grpc.GetFeedPricesUSD(ctx, &ccipocr3pb.GetFeedPricesUSDRequest{ + Tokens: tokenStrs, + TokenInfo: tokenInfoMapToPb(tokenInfo), + }) + if err != nil { + return nil, err + } + return pbToTokenPriceMap(resp.Prices), nil +} + +func (c *chainAccessorClient) GetFeeQuoterTokenUpdates(ctx context.Context, tokens []ccipocr3.UnknownEncodedAddress, chain ccipocr3.ChainSelector) (map[ccipocr3.UnknownEncodedAddress]ccipocr3.TimestampedUnixBig, error) { + var tokenStrs []string + for _, token := range tokens { + tokenStrs = append(tokenStrs, string(token)) + } + + resp, err := c.grpc.GetFeeQuoterTokenUpdates(ctx, &ccipocr3pb.GetFeeQuoterTokenUpdatesRequest{ + Tokens: tokenStrs, + ChainSelector: uint64(chain), + }) + if err != nil { + return nil, err + } + return pbToTokenUpdatesUnix(resp.TokenUpdates), nil +} + // Server implementation var _ ccipocr3pb.ChainAccessorServer = (*chainAccessorServer)(nil) @@ -470,13 +591,16 @@ func (s *chainAccessorServer) GetChainFeePriceUpdate(ctx context.Context, req *c chainSelectors = append(chainSelectors, ccipocr3.ChainSelector(sel)) } - priceUpdates := s.impl.GetChainFeePriceUpdate(ctx, chainSelectors) + priceUpdates, err := s.impl.GetChainFeePriceUpdate(ctx, chainSelectors) + if err != nil { + return nil, err + } - pbUpdates := make(map[uint64]*ccipocr3pb.TimestampedBig) + pbUpdates := make(map[uint64]*ccipocr3pb.TimestampedUnixBig) for chainSel, update := range priceUpdates { - pbUpdates[uint64(chainSel)] = &ccipocr3pb.TimestampedBig{ - Value: intToPbBigInt(update.Value.Int), - Timestamp: timestamppb.New(update.Timestamp), + pbUpdates[uint64(chainSel)] = &ccipocr3pb.TimestampedUnixBig{ + Value: intToPbBigInt(update.Value), + Timestamp: update.Timestamp, } } @@ -490,7 +614,7 @@ func (s *chainAccessorServer) GetLatestPriceSeqNr(ctx context.Context, req *empt if err != nil { return nil, err } - return &ccipocr3pb.GetLatestPriceSeqNrResponse{SeqNr: seqNr}, nil + return &ccipocr3pb.GetLatestPriceSeqNrResponse{SeqNr: uint64(seqNr)}, nil } // SourceAccessor server methods @@ -555,3 +679,63 @@ func (s *chainAccessorServer) GetFeeQuoterDestChainConfig(ctx context.Context, r Config: feeQuoterDestChainConfigToPb(config), }, nil } + +// USDCMessageReader server methods +func (s *chainAccessorServer) MessagesByTokenID(ctx context.Context, req *ccipocr3pb.MessagesByTokenIDRequest) (*ccipocr3pb.MessagesByTokenIDResponse, error) { + tokens, err := pbToMessageTokenIDMap(req.Tokens) + if err != nil { + return nil, err + } + + messages, err := s.impl.MessagesByTokenID( + ctx, + ccipocr3.ChainSelector(req.SourceChainSelector), + ccipocr3.ChainSelector(req.DestChainSelector), + tokens, + ) + if err != nil { + return nil, err + } + + return &ccipocr3pb.MessagesByTokenIDResponse{ + Messages: messagesByTokenIDToPb(messages), + }, nil +} + +// PriceReader server methods +func (s *chainAccessorServer) GetFeedPricesUSD(ctx context.Context, req *ccipocr3pb.GetFeedPricesUSDRequest) (*ccipocr3pb.GetFeedPricesUSDResponse, error) { + var tokens []ccipocr3.UnknownEncodedAddress + for _, tokenStr := range req.Tokens { + tokens = append(tokens, ccipocr3.UnknownEncodedAddress(tokenStr)) + } + tokenInfo := pbToTokenInfoMap(req.TokenInfo) + + prices, err := s.impl.GetFeedPricesUSD(ctx, tokens, tokenInfo) + if err != nil { + return nil, err + } + + return &ccipocr3pb.GetFeedPricesUSDResponse{ + Prices: tokenPriceMapToPb(prices), + }, nil +} + +func (s *chainAccessorServer) GetFeeQuoterTokenUpdates(ctx context.Context, req *ccipocr3pb.GetFeeQuoterTokenUpdatesRequest) (*ccipocr3pb.GetFeeQuoterTokenUpdatesResponse, error) { + var tokens []ccipocr3.UnknownEncodedAddress + for _, tokenStr := range req.Tokens { + tokens = append(tokens, ccipocr3.UnknownEncodedAddress(tokenStr)) + } + + updates, err := s.impl.GetFeeQuoterTokenUpdates( + ctx, + tokens, + ccipocr3.ChainSelector(req.ChainSelector), + ) + if err != nil { + return nil, err + } + + return &ccipocr3pb.GetFeeQuoterTokenUpdatesResponse{ + TokenUpdates: tokenUpdatesUnixToPb(updates), + }, nil +} diff --git a/pkg/loop/internal/relayer/pluginprovider/ext/ccipocr3/convert.go b/pkg/loop/internal/relayer/pluginprovider/ext/ccipocr3/convert.go index f09a0967c..c930cc165 100644 --- a/pkg/loop/internal/relayer/pluginprovider/ext/ccipocr3/convert.go +++ b/pkg/loop/internal/relayer/pluginprovider/ext/ccipocr3/convert.go @@ -11,9 +11,17 @@ import ( "github.com/smartcontractkit/chainlink-protos/cre/go/values/pb" ) -// Helper function to convert protobuf BigInt to big.Int +// Helper function to convert protobuf BigInt to big.Int, preserves nil func pbBigIntToInt(b *ccipocr3pb.BigInt) *big.Int { - if b == nil || len(b.Value) == 0 { + if b == nil { + return nil + } + + if b.Value == nil { + return nil + } + + if len(b.Value) == 0 { return big.NewInt(0) } return new(big.Int).SetBytes(b.Value) @@ -21,16 +29,24 @@ func pbBigIntToInt(b *ccipocr3pb.BigInt) *big.Int { // Helper function to convert protobuf BigInt to ccipocr3.BigInt, preserving nil func pbToBigInt(b *ccipocr3pb.BigInt) ccipocr3.BigInt { - if b == nil || len(b.Value) == 0 { + if b == nil { return ccipocr3.BigInt{Int: nil} } + + if b.Value == nil { + return ccipocr3.BigInt{Int: nil} + } + + if len(b.Value) == 0 { + return ccipocr3.BigInt{Int: big.NewInt(0)} + } return ccipocr3.NewBigInt(new(big.Int).SetBytes(b.Value)) } // Helper function to convert big.Int to protobuf BigInt func intToPbBigInt(i *big.Int) *ccipocr3pb.BigInt { if i == nil { - return &ccipocr3pb.BigInt{Value: []byte{}} + return nil } return &ccipocr3pb.BigInt{Value: i.Bytes()} } @@ -742,3 +758,170 @@ func pbToCurseInfo(pb *ccipocr3pb.CurseInfo) ccipocr3.CurseInfo { } return result } + +func pbToTokenPriceMap(pbMap map[string]*ccipocr3pb.BigInt) ccipocr3.TokenPriceMap { + if pbMap == nil { + return nil + } + result := make(ccipocr3.TokenPriceMap) + for token, pbPrice := range pbMap { + result[ccipocr3.UnknownEncodedAddress(token)] = pbToBigInt(pbPrice) + } + return result +} + +func tokenPriceMapToPb(priceMap ccipocr3.TokenPriceMap) map[string]*ccipocr3pb.BigInt { + if priceMap == nil { + return nil + } + result := make(map[string]*ccipocr3pb.BigInt) + for token, price := range priceMap { + result[string(token)] = intToPbBigInt(price.Int) + } + return result +} + +func pbToMessageTokenIDMap(pbTokens map[string]*ccipocr3pb.RampTokenAmount) (map[ccipocr3.MessageTokenID]ccipocr3.RampTokenAmount, error) { + if pbTokens == nil { + return nil, nil + } + result := make(map[ccipocr3.MessageTokenID]ccipocr3.RampTokenAmount) + for tokenIDStr, pbAmount := range pbTokens { + // Parse MessageTokenID from string (format: "seqNr_index") + var seqNr uint64 + var index int + if _, err := fmt.Sscanf(tokenIDStr, "%d_%d", &seqNr, &index); err != nil { + return nil, fmt.Errorf("failed to parse MessageTokenID from string %s: %w", tokenIDStr, err) + } + + tokenID := ccipocr3.NewMessageTokenID(ccipocr3.SeqNum(seqNr), index) + result[tokenID] = ccipocr3.RampTokenAmount{ + SourcePoolAddress: pbAmount.SourcePoolAddress, + DestTokenAddress: pbAmount.DestTokenAddress, + ExtraData: pbAmount.ExtraData, + Amount: pbToBigInt(pbAmount.Amount), + } + } + return result, nil +} + +func messageTokenIDMapToPb(tokens map[ccipocr3.MessageTokenID]ccipocr3.RampTokenAmount) map[string]*ccipocr3pb.RampTokenAmount { + if tokens == nil { + return nil + } + result := make(map[string]*ccipocr3pb.RampTokenAmount) + for tokenID, amount := range tokens { + result[tokenID.String()] = &ccipocr3pb.RampTokenAmount{ + SourcePoolAddress: []byte(amount.SourcePoolAddress), + DestTokenAddress: []byte(amount.DestTokenAddress), + ExtraData: []byte(amount.ExtraData), + Amount: intToPbBigInt(amount.Amount.Int), + } + } + return result +} + +func pbToMessagesByTokenID(pbMessages map[string][]byte) (map[ccipocr3.MessageTokenID]ccipocr3.Bytes, error) { + if pbMessages == nil { + return nil, nil + } + result := make(map[ccipocr3.MessageTokenID]ccipocr3.Bytes) + for tokenIDStr, messageBytes := range pbMessages { + // Parse MessageTokenID from string (format: "seqNr_index") + var seqNr uint64 + var index int + if _, err := fmt.Sscanf(tokenIDStr, "%d_%d", &seqNr, &index); err != nil { + return nil, fmt.Errorf("failed to parse MessageTokenID from string %s: %w", tokenIDStr, err) + } + + tokenID := ccipocr3.NewMessageTokenID(ccipocr3.SeqNum(seqNr), index) + result[tokenID] = ccipocr3.Bytes(messageBytes) + } + return result, nil +} + +func messagesByTokenIDToPb(messages map[ccipocr3.MessageTokenID]ccipocr3.Bytes) map[string][]byte { + if messages == nil { + return nil + } + result := make(map[string][]byte) + for tokenID, messageBytes := range messages { + result[tokenID.String()] = []byte(messageBytes) + } + return result +} + +func pbToTokenUpdatesUnix(pbUpdates map[string]*ccipocr3pb.TimestampedUnixBig) map[ccipocr3.UnknownEncodedAddress]ccipocr3.TimestampedUnixBig { + if pbUpdates == nil { + return nil + } + result := make(map[ccipocr3.UnknownEncodedAddress]ccipocr3.TimestampedUnixBig) + for token, pbUpdate := range pbUpdates { + var value *big.Int + if pbUpdate.Value != nil && len(pbUpdate.Value.Value) > 0 { + value = new(big.Int).SetBytes(pbUpdate.Value.Value) + } else { + value = big.NewInt(0) + } + result[ccipocr3.UnknownEncodedAddress(token)] = ccipocr3.TimestampedUnixBig{ + Timestamp: pbUpdate.Timestamp, + Value: value, + } + } + return result +} + +func tokenUpdatesUnixToPb(updates map[ccipocr3.UnknownEncodedAddress]ccipocr3.TimestampedUnixBig) map[string]*ccipocr3pb.TimestampedUnixBig { + if updates == nil { + return nil + } + result := make(map[string]*ccipocr3pb.TimestampedUnixBig) + for token, update := range updates { + result[string(token)] = &ccipocr3pb.TimestampedUnixBig{ + Timestamp: update.Timestamp, + Value: intToPbBigInt(update.Value), + } + } + return result +} + +func pbToTokenInfo(pb *ccipocr3pb.TokenInfo) ccipocr3.TokenInfo { + if pb == nil { + return ccipocr3.TokenInfo{} + } + return ccipocr3.TokenInfo{ + AggregatorAddress: ccipocr3.UnknownEncodedAddress(pb.AggregatorAddress), + DeviationPPB: pbToBigInt(pb.DeviationPpb), + Decimals: uint8(pb.Decimals), + } +} + +func tokenInfoToPb(info ccipocr3.TokenInfo) *ccipocr3pb.TokenInfo { + return &ccipocr3pb.TokenInfo{ + AggregatorAddress: string(info.AggregatorAddress), + DeviationPpb: intToPbBigInt(info.DeviationPPB.Int), + Decimals: uint32(info.Decimals), + } +} + +func pbToTokenInfoMap(pbMap map[string]*ccipocr3pb.TokenInfo) map[ccipocr3.UnknownEncodedAddress]ccipocr3.TokenInfo { + if pbMap == nil { + return nil + } + result := make(map[ccipocr3.UnknownEncodedAddress]ccipocr3.TokenInfo) + for token, pbInfo := range pbMap { + result[ccipocr3.UnknownEncodedAddress(token)] = pbToTokenInfo(pbInfo) + } + return result +} + +func tokenInfoMapToPb(infoMap map[ccipocr3.UnknownEncodedAddress]ccipocr3.TokenInfo) map[string]*ccipocr3pb.TokenInfo { + if infoMap == nil { + return nil + } + result := make(map[string]*ccipocr3pb.TokenInfo) + for token, info := range infoMap { + result[string(token)] = tokenInfoToPb(info) + } + return result +} diff --git a/pkg/loop/internal/relayer/pluginprovider/ext/ccipocr3/convert_test.go b/pkg/loop/internal/relayer/pluginprovider/ext/ccipocr3/convert_test.go index 46e09d779..6f3645e19 100644 --- a/pkg/loop/internal/relayer/pluginprovider/ext/ccipocr3/convert_test.go +++ b/pkg/loop/internal/relayer/pluginprovider/ext/ccipocr3/convert_test.go @@ -1,13 +1,16 @@ package ccipocr3 import ( + "fmt" "math" "math/big" "testing" + "time" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + ccipocr3pb "github.com/smartcontractkit/chainlink-common/pkg/loop/internal/pb/ccipocr3" "github.com/smartcontractkit/chainlink-common/pkg/types/ccipocr3" "github.com/smartcontractkit/chainlink-protos/cre/go/values/pb" ) @@ -92,7 +95,17 @@ func TestMessageProtobufFlattening(t *testing.T) { assert.Equal(t, []byte(tc.message.Receiver), pbMessage.Receiver) assert.Equal(t, []byte(tc.message.ExtraArgs), pbMessage.ExtraArgs) assert.Equal(t, []byte(tc.message.FeeToken), pbMessage.FeeToken) - assert.NotNil(t, pbMessage.FeeValueJuels) + // With nil BigInt values, protobuf fields should be nil + if tc.message.FeeTokenAmount.Int == nil { + assert.Nil(t, pbMessage.FeeTokenAmount) + } else { + assert.NotNil(t, pbMessage.FeeTokenAmount) + } + if tc.message.FeeValueJuels.Int == nil { + assert.Nil(t, pbMessage.FeeValueJuels) + } else { + assert.NotNil(t, pbMessage.FeeValueJuels) + } // Convert back to Go struct convertedMessage := pbToMessage(pbMessage) @@ -648,3 +661,936 @@ func TestSourceChainConfigNilHandling(t *testing.T) { assert.Equal(t, []byte(nil), pbConfig.OnRamp) }) } + +// TestTokenPriceMapConversion tests the new TokenPriceMap conversion functions +func TestTokenPriceMapConversion(t *testing.T) { + testCases := []struct { + name string + priceMap ccipocr3.TokenPriceMap + }{ + { + name: "TokenPriceMap with multiple tokens", + priceMap: ccipocr3.TokenPriceMap{ + ccipocr3.UnknownEncodedAddress("token1"): ccipocr3.NewBigInt(big.NewInt(1000000)), + ccipocr3.UnknownEncodedAddress("token2"): ccipocr3.NewBigInt(big.NewInt(2500000)), + ccipocr3.UnknownEncodedAddress("token3"): ccipocr3.NewBigInt(big.NewInt(500000)), + }, + }, + { + name: "Empty TokenPriceMap", + priceMap: ccipocr3.TokenPriceMap{}, + }, + { + name: "TokenPriceMap with zero prices", + priceMap: ccipocr3.TokenPriceMap{ + ccipocr3.UnknownEncodedAddress("zero-token"): ccipocr3.NewBigInt(big.NewInt(0)), + }, + }, + { + name: "TokenPriceMap with large prices", + priceMap: ccipocr3.TokenPriceMap{ + ccipocr3.UnknownEncodedAddress("large-token"): func() ccipocr3.BigInt { + val, _ := new(big.Int).SetString("999999999999999999999999999999", 10) + return ccipocr3.NewBigInt(val) + }(), + }, + }, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + // Convert Go -> Protobuf + pbMap := tokenPriceMapToPb(tc.priceMap) + + if tc.priceMap == nil { + assert.Nil(t, pbMap) + return + } + + require.NotNil(t, pbMap) + assert.Equal(t, len(tc.priceMap), len(pbMap)) + + // Verify protobuf values + for token, price := range tc.priceMap { + pbPrice, exists := pbMap[string(token)] + require.True(t, exists, "token %s should exist in protobuf map", string(token)) + require.NotNil(t, pbPrice) + assert.Equal(t, price.Int.Bytes(), pbPrice.Value) + } + + // Convert Protobuf -> Go (round-trip) + convertedMap := pbToTokenPriceMap(pbMap) + + // Verify round-trip conversion + assert.Equal(t, len(tc.priceMap), len(convertedMap)) + for token, originalPrice := range tc.priceMap { + convertedPrice, exists := convertedMap[token] + require.True(t, exists, "token %s should exist in converted map", string(token)) + assert.Equal(t, originalPrice.Int.String(), convertedPrice.Int.String(), "price should survive round-trip for token %s", string(token)) + } + }) + } +} + +func TestTokenPriceMapNilHandling(t *testing.T) { + t.Run("nil TokenPriceMap to protobuf", func(t *testing.T) { + pbMap := tokenPriceMapToPb(nil) + assert.Nil(t, pbMap) + }) + + t.Run("nil protobuf map to TokenPriceMap", func(t *testing.T) { + priceMap := pbToTokenPriceMap(nil) + assert.Nil(t, priceMap) + }) + + t.Run("empty protobuf map to TokenPriceMap", func(t *testing.T) { + emptyPbMap := make(map[string]*ccipocr3pb.BigInt) + priceMap := pbToTokenPriceMap(emptyPbMap) + require.NotNil(t, priceMap) + assert.Equal(t, 0, len(priceMap)) + }) +} + +// TestMessageTokenIDMapConversion tests the MessageTokenID map conversion functions +func TestMessageTokenIDMapConversion(t *testing.T) { + testCases := []struct { + name string + tokenMap map[ccipocr3.MessageTokenID]ccipocr3.RampTokenAmount + }{ + { + name: "MessageTokenID map with multiple tokens", + tokenMap: map[ccipocr3.MessageTokenID]ccipocr3.RampTokenAmount{ + ccipocr3.NewMessageTokenID(1, 0): { + SourcePoolAddress: ccipocr3.UnknownAddress("source-pool-1"), + DestTokenAddress: ccipocr3.UnknownAddress("dest-token-1"), + ExtraData: ccipocr3.Bytes("extra-data-1"), + Amount: ccipocr3.NewBigInt(big.NewInt(1000)), + }, + ccipocr3.NewMessageTokenID(2, 1): { + SourcePoolAddress: ccipocr3.UnknownAddress("source-pool-2"), + DestTokenAddress: ccipocr3.UnknownAddress("dest-token-2"), + ExtraData: ccipocr3.Bytes("extra-data-2"), + Amount: ccipocr3.NewBigInt(big.NewInt(2000)), + }, + ccipocr3.NewMessageTokenID(10, 5): { + SourcePoolAddress: ccipocr3.UnknownAddress("source-pool-10"), + DestTokenAddress: ccipocr3.UnknownAddress("dest-token-10"), + ExtraData: ccipocr3.Bytes(""), + Amount: ccipocr3.NewBigInt(big.NewInt(0)), + }, + }, + }, + { + name: "Empty MessageTokenID map", + tokenMap: map[ccipocr3.MessageTokenID]ccipocr3.RampTokenAmount{}, + }, + { + name: "Single MessageTokenID with large values", + tokenMap: map[ccipocr3.MessageTokenID]ccipocr3.RampTokenAmount{ + ccipocr3.NewMessageTokenID(999999, 255): { + SourcePoolAddress: ccipocr3.UnknownAddress("very-long-source-pool-address-with-many-characters"), + DestTokenAddress: ccipocr3.UnknownAddress("very-long-dest-token-address-with-many-characters"), + ExtraData: ccipocr3.Bytes("very long extra data with many characters that tests the handling of large data"), + Amount: func() ccipocr3.BigInt { + val, _ := new(big.Int).SetString("123456789012345678901234567890", 10) + return ccipocr3.NewBigInt(val) + }(), + }, + }, + }, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + // Convert Go -> Protobuf + pbMap := messageTokenIDMapToPb(tc.tokenMap) + + if tc.tokenMap == nil { + assert.Nil(t, pbMap) + return + } + + require.NotNil(t, pbMap) + assert.Equal(t, len(tc.tokenMap), len(pbMap)) + + // Verify protobuf values + for tokenID, amount := range tc.tokenMap { + tokenIDStr := tokenID.String() + pbAmount, exists := pbMap[tokenIDStr] + require.True(t, exists, "tokenID %s should exist in protobuf map", tokenIDStr) + require.NotNil(t, pbAmount) + assert.Equal(t, []byte(amount.SourcePoolAddress), pbAmount.SourcePoolAddress) + assert.Equal(t, []byte(amount.DestTokenAddress), pbAmount.DestTokenAddress) + assert.Equal(t, []byte(amount.ExtraData), pbAmount.ExtraData) + assert.Equal(t, amount.Amount.Int.Bytes(), pbAmount.Amount.Value) + } + + // Convert Protobuf -> Go (round-trip) + convertedMap, err := pbToMessageTokenIDMap(pbMap) + require.NoError(t, err) + + // Verify round-trip conversion + assert.Equal(t, len(tc.tokenMap), len(convertedMap)) + for tokenID, originalAmount := range tc.tokenMap { + convertedAmount, exists := convertedMap[tokenID] + require.True(t, exists, "tokenID %s should exist in converted map", tokenID.String()) + assert.Equal(t, []byte(originalAmount.SourcePoolAddress), []byte(convertedAmount.SourcePoolAddress)) + assert.Equal(t, []byte(originalAmount.DestTokenAddress), []byte(convertedAmount.DestTokenAddress)) + assert.Equal(t, []byte(originalAmount.ExtraData), []byte(convertedAmount.ExtraData)) + assert.Equal(t, originalAmount.Amount.Int.String(), convertedAmount.Amount.Int.String()) + } + }) + } +} + +func TestMessageTokenIDMapErrorHandling(t *testing.T) { + t.Run("invalid tokenID string should return error", func(t *testing.T) { + pbMap := map[string]*ccipocr3pb.RampTokenAmount{ + "invalid-format": { + SourcePoolAddress: []byte("test"), + DestTokenAddress: []byte("test"), + ExtraData: []byte("test"), + Amount: &ccipocr3pb.BigInt{Value: []byte{0x01}}, + }, + } + + _, err := pbToMessageTokenIDMap(pbMap) + assert.Error(t, err) + assert.Contains(t, err.Error(), "failed to parse MessageTokenID") + }) + + t.Run("nil protobuf map should not error", func(t *testing.T) { + result, err := pbToMessageTokenIDMap(nil) + assert.NoError(t, err) + assert.Nil(t, result) + }) + + t.Run("nil Go map should return nil", func(t *testing.T) { + result := messageTokenIDMapToPb(nil) + assert.Nil(t, result) + }) +} + +// TestMessagesByTokenIDConversion tests the messages by token ID conversion functions +func TestMessagesByTokenIDConversion(t *testing.T) { + testCases := []struct { + name string + messages map[ccipocr3.MessageTokenID]ccipocr3.Bytes + }{ + { + name: "Messages with multiple token IDs", + messages: map[ccipocr3.MessageTokenID]ccipocr3.Bytes{ + ccipocr3.NewMessageTokenID(1, 0): ccipocr3.Bytes("usdc-message-data-1"), + ccipocr3.NewMessageTokenID(2, 1): ccipocr3.Bytes("usdc-message-data-2"), + ccipocr3.NewMessageTokenID(5, 3): ccipocr3.Bytes("usdc-message-data-5"), + }, + }, + { + name: "Empty messages map", + messages: map[ccipocr3.MessageTokenID]ccipocr3.Bytes{}, + }, + { + name: "Messages with binary data", + messages: map[ccipocr3.MessageTokenID]ccipocr3.Bytes{ + ccipocr3.NewMessageTokenID(100, 50): ccipocr3.Bytes([]byte{0x01, 0x02, 0x03, 0xFF, 0xFE, 0xFD}), + }, + }, + { + name: "Messages with empty data", + messages: map[ccipocr3.MessageTokenID]ccipocr3.Bytes{ + ccipocr3.NewMessageTokenID(0, 0): ccipocr3.Bytes(""), + }, + }, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + // Convert Go -> Protobuf + pbMap := messagesByTokenIDToPb(tc.messages) + + if tc.messages == nil { + assert.Nil(t, pbMap) + return + } + + require.NotNil(t, pbMap) + assert.Equal(t, len(tc.messages), len(pbMap)) + + // Verify protobuf values + for tokenID, messageBytes := range tc.messages { + tokenIDStr := tokenID.String() + pbBytes, exists := pbMap[tokenIDStr] + require.True(t, exists, "tokenID %s should exist in protobuf map", tokenIDStr) + assert.Equal(t, []byte(messageBytes), pbBytes) + } + + // Convert Protobuf -> Go (round-trip) + convertedMap, err := pbToMessagesByTokenID(pbMap) + require.NoError(t, err) + + // Verify round-trip conversion + assert.Equal(t, len(tc.messages), len(convertedMap)) + for tokenID, originalBytes := range tc.messages { + convertedBytes, exists := convertedMap[tokenID] + require.True(t, exists, "tokenID %s should exist in converted map", tokenID.String()) + assert.Equal(t, []byte(originalBytes), []byte(convertedBytes)) + } + }) + } +} + +func TestMessagesByTokenIDErrorHandling(t *testing.T) { + t.Run("invalid tokenID string should return error", func(t *testing.T) { + pbMap := map[string][]byte{ + "not-a-valid-format": []byte("test-message"), + } + + _, err := pbToMessagesByTokenID(pbMap) + assert.Error(t, err) + assert.Contains(t, err.Error(), "failed to parse MessageTokenID") + }) + + t.Run("nil protobuf map should not error", func(t *testing.T) { + result, err := pbToMessagesByTokenID(nil) + assert.NoError(t, err) + assert.Nil(t, result) + }) + + t.Run("nil Go map should return nil", func(t *testing.T) { + result := messagesByTokenIDToPb(nil) + assert.Nil(t, result) + }) +} + +// TestTokenUpdatesUnixConversion tests the TimestampedUnixBig token updates conversion functions +func TestTokenUpdatesUnixConversion(t *testing.T) { + testTime := time.Date(2024, 1, 15, 12, 0, 0, 0, time.UTC) + + testCases := []struct { + name string + updates map[ccipocr3.UnknownEncodedAddress]ccipocr3.TimestampedUnixBig + }{ + { + name: "Unix token updates with multiple tokens", + updates: map[ccipocr3.UnknownEncodedAddress]ccipocr3.TimestampedUnixBig{ + ccipocr3.UnknownEncodedAddress("token1"): { + Timestamp: uint32(testTime.Unix()), + Value: big.NewInt(1500000), + }, + ccipocr3.UnknownEncodedAddress("token2"): { + Timestamp: uint32(testTime.Add(time.Hour).Unix()), + Value: big.NewInt(2500000), + }, + ccipocr3.UnknownEncodedAddress("token3"): { + Timestamp: uint32(testTime.Add(2 * time.Hour).Unix()), + Value: big.NewInt(750000), + }, + }, + }, + { + name: "Empty unix token updates", + updates: map[ccipocr3.UnknownEncodedAddress]ccipocr3.TimestampedUnixBig{}, + }, + { + name: "Unix token update with zero value", + updates: map[ccipocr3.UnknownEncodedAddress]ccipocr3.TimestampedUnixBig{ + ccipocr3.UnknownEncodedAddress("zero-token"): { + Timestamp: uint32(testTime.Unix()), + Value: big.NewInt(0), + }, + }, + }, + { + name: "Unix token update with large value", + updates: map[ccipocr3.UnknownEncodedAddress]ccipocr3.TimestampedUnixBig{ + ccipocr3.UnknownEncodedAddress("large-token"): { + Timestamp: uint32(testTime.Unix()), + Value: func() *big.Int { + val, _ := new(big.Int).SetString("999999999999999999999999999999", 10) + return val + }(), + }, + }, + }, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + // Convert Go -> Protobuf + pbMap := tokenUpdatesUnixToPb(tc.updates) + + if tc.updates == nil { + assert.Nil(t, pbMap) + return + } + + require.NotNil(t, pbMap) + assert.Equal(t, len(tc.updates), len(pbMap)) + + // Verify protobuf values + for token, update := range tc.updates { + pbUpdate, exists := pbMap[string(token)] + require.True(t, exists, "token %s should exist in protobuf map", string(token)) + require.NotNil(t, pbUpdate) + require.NotNil(t, pbUpdate.Value) + + assert.Equal(t, update.Timestamp, pbUpdate.Timestamp) + assert.Equal(t, update.Value.Bytes(), pbUpdate.Value.Value) + } + + // Convert Protobuf -> Go (round-trip) + convertedMap := pbToTokenUpdatesUnix(pbMap) + + // Verify round-trip conversion + assert.Equal(t, len(tc.updates), len(convertedMap)) + for token, originalUpdate := range tc.updates { + convertedUpdate, exists := convertedMap[token] + require.True(t, exists, "token %s should exist in converted map", string(token)) + + assert.Equal(t, originalUpdate.Timestamp, convertedUpdate.Timestamp) + assert.Equal(t, originalUpdate.Value.String(), convertedUpdate.Value.String()) + } + }) + } +} + +func TestTokenUpdatesUnixNilHandling(t *testing.T) { + t.Run("nil unix token updates to protobuf", func(t *testing.T) { + pbMap := tokenUpdatesUnixToPb(nil) + assert.Nil(t, pbMap) + }) + + t.Run("nil protobuf map to unix token updates", func(t *testing.T) { + updates := pbToTokenUpdatesUnix(nil) + assert.Nil(t, updates) + }) + + t.Run("empty protobuf map to unix token updates", func(t *testing.T) { + emptyPbMap := make(map[string]*ccipocr3pb.TimestampedUnixBig) + updates := pbToTokenUpdatesUnix(emptyPbMap) + require.NotNil(t, updates) + assert.Equal(t, 0, len(updates)) + }) + + t.Run("protobuf map with nil value", func(t *testing.T) { + pbMap := map[string]*ccipocr3pb.TimestampedUnixBig{ + "test-token": { + Timestamp: 1705320000, // Some valid unix timestamp + Value: nil, + }, + } + + // Should not panic and handle gracefully + updates := pbToTokenUpdatesUnix(pbMap) + require.NotNil(t, updates) + require.Contains(t, updates, ccipocr3.UnknownEncodedAddress("test-token")) + + // When value is nil, should default to zero big.Int + update := updates[("test-token")] + assert.Equal(t, uint32(1705320000), update.Timestamp) + assert.Equal(t, big.NewInt(0), update.Value) + }) +} + +// TestPbBigIntToInt tests the pbBigIntToInt function with various inputs +func TestPbBigIntToInt(t *testing.T) { + testCases := []struct { + name string + input *ccipocr3pb.BigInt + expected *big.Int + }{ + { + name: "nil input", + input: nil, + expected: nil, + }, + { + name: "empty value bytes", // empty bytes are treated as zero + input: &ccipocr3pb.BigInt{Value: []byte{}}, + expected: big.NewInt(0), + }, + { + name: "nil value bytes", + input: &ccipocr3pb.BigInt{Value: nil}, + expected: nil, + }, + { + name: "zero value", + input: &ccipocr3pb.BigInt{Value: big.NewInt(0).Bytes()}, + expected: big.NewInt(0), + }, + { + name: "positive small integer", + input: &ccipocr3pb.BigInt{Value: big.NewInt(42).Bytes()}, + expected: big.NewInt(42), + }, + { + name: "positive large integer", + input: &ccipocr3pb.BigInt{Value: big.NewInt(1234567890).Bytes()}, + expected: big.NewInt(1234567890), + }, + { + name: "very large positive integer", + input: &ccipocr3pb.BigInt{Value: func() []byte { + val := new(big.Int) + val.SetString("999999999999999999999999999999", 10) + return val.Bytes() + }()}, + expected: func() *big.Int { + val := new(big.Int) + val.SetString("999999999999999999999999999999", 10) + return val + }(), + }, + { + name: "maximum uint64 value", + input: &ccipocr3pb.BigInt{Value: func() []byte { + val := new(big.Int) + val.SetUint64(^uint64(0)) // max uint64 + return val.Bytes() + }()}, + expected: func() *big.Int { + val := new(big.Int) + val.SetUint64(^uint64(0)) + return val + }(), + }, + { + name: "256-bit integer (32 bytes)", + input: &ccipocr3pb.BigInt{Value: func() []byte { + // Create a 256-bit integer (all bits set) + bytes := make([]byte, 32) + for i := range bytes { + bytes[i] = 0xFF + } + return bytes + }()}, + expected: func() *big.Int { + bytes := make([]byte, 32) + for i := range bytes { + bytes[i] = 0xFF + } + return new(big.Int).SetBytes(bytes) + }(), + }, + { + name: "single byte value", + input: &ccipocr3pb.BigInt{Value: []byte{0xFF}}, + expected: big.NewInt(255), + }, + { + name: "two byte value", + input: &ccipocr3pb.BigInt{Value: []byte{0x01, 0x00}}, + expected: big.NewInt(256), + }, + { + name: "leading zero bytes (should be handled correctly)", + input: &ccipocr3pb.BigInt{Value: []byte{0x00, 0x00, 0x01, 0x00}}, + expected: big.NewInt(256), + }, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + result := pbBigIntToInt(tc.input) + + // Handle nil comparisons specially + if tc.expected == nil { + assert.Nil(t, result, "result should be nil when expected is nil") + } else { + assert.NotNil(t, result, "result should not be nil when expected is not nil") + assert.Equal(t, tc.expected.String(), result.String(), "converted big.Int should match expected value") + assert.Equal(t, tc.expected.Cmp(result), 0, "big.Int comparison should be equal") + } + }) + } +} + +// TestPbToBigInt tests the pbToBigInt function with various inputs +func TestPbToBigInt(t *testing.T) { + testCases := []struct { + name string + input *ccipocr3pb.BigInt + expected ccipocr3.BigInt + }{ + { + name: "nil input should preserve nil", + input: nil, + expected: ccipocr3.BigInt{Int: nil}, + }, + { + name: "empty value bytes should return zero BigInt", + input: &ccipocr3pb.BigInt{Value: []byte{}}, + expected: ccipocr3.BigInt{Int: big.NewInt(0)}, + }, + { + name: "nil value bytes should preserve nil", + input: &ccipocr3pb.BigInt{Value: nil}, + expected: ccipocr3.BigInt{Int: nil}, + }, + { + name: "zero value", + input: &ccipocr3pb.BigInt{Value: big.NewInt(0).Bytes()}, + expected: ccipocr3.NewBigInt(big.NewInt(0)), + }, + { + name: "positive small integer", + input: &ccipocr3pb.BigInt{Value: big.NewInt(123).Bytes()}, + expected: ccipocr3.NewBigInt(big.NewInt(123)), + }, + { + name: "positive large integer", + input: &ccipocr3pb.BigInt{Value: big.NewInt(9876543210).Bytes()}, + expected: ccipocr3.NewBigInt(big.NewInt(9876543210)), + }, + { + name: "very large positive integer", + input: &ccipocr3pb.BigInt{Value: func() []byte { + val := new(big.Int) + val.SetString("123456789012345678901234567890", 10) + return val.Bytes() + }()}, + expected: func() ccipocr3.BigInt { + val := new(big.Int) + val.SetString("123456789012345678901234567890", 10) + return ccipocr3.NewBigInt(val) + }(), + }, + { + name: "maximum uint64 value", + input: &ccipocr3pb.BigInt{Value: func() []byte { + val := new(big.Int) + val.SetUint64(^uint64(0)) // max uint64 + return val.Bytes() + }()}, + expected: func() ccipocr3.BigInt { + val := new(big.Int) + val.SetUint64(^uint64(0)) + return ccipocr3.NewBigInt(val) + }(), + }, + { + name: "256-bit integer (32 bytes)", + input: &ccipocr3pb.BigInt{Value: func() []byte { + // Create a 256-bit integer + bytes := make([]byte, 32) + for i := range bytes { + bytes[i] = 0xAA // alternating bit pattern + } + return bytes + }()}, + expected: func() ccipocr3.BigInt { + bytes := make([]byte, 32) + for i := range bytes { + bytes[i] = 0xAA + } + return ccipocr3.NewBigInt(new(big.Int).SetBytes(bytes)) + }(), + }, + { + name: "single byte maximum value", + input: &ccipocr3pb.BigInt{Value: []byte{0xFF}}, + expected: ccipocr3.NewBigInt(big.NewInt(255)), + }, + { + name: "two byte value", + input: &ccipocr3pb.BigInt{Value: []byte{0xFF, 0xFF}}, + expected: ccipocr3.NewBigInt(big.NewInt(65535)), + }, + { + name: "ethereum wei amount (18 decimals)", + input: &ccipocr3pb.BigInt{Value: func() []byte { + // 1 ETH in wei = 10^18 + val := new(big.Int) + val.SetString("1000000000000000000", 10) + return val.Bytes() + }()}, + expected: func() ccipocr3.BigInt { + val := new(big.Int) + val.SetString("1000000000000000000", 10) + return ccipocr3.NewBigInt(val) + }(), + }, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + result := pbToBigInt(tc.input) + + // Handle nil comparisons specially + if tc.expected.Int == nil { + assert.Nil(t, result.Int, "result.Int should be nil when expected is nil") + } else { + assert.NotNil(t, result.Int, "result.Int should not be nil when expected is not nil") + assert.Equal(t, tc.expected.Int.String(), result.Int.String(), "converted BigInt should match expected value") + assert.Equal(t, tc.expected.Int.Cmp(result.Int), 0, "BigInt comparison should be equal") + } + }) + } +} + +// TestPbBigIntRoundTrip tests round-trip conversion between protobuf BigInt and Go big.Int +func TestPbBigIntRoundTrip(t *testing.T) { + testValues := []*big.Int{ + nil, // Test nil value + big.NewInt(0), + big.NewInt(1), + big.NewInt(42), + big.NewInt(255), + big.NewInt(256), + big.NewInt(65535), + big.NewInt(65536), + big.NewInt(1234567890), + func() *big.Int { + val := new(big.Int) + val.SetString("999999999999999999999999999999", 10) + return val + }(), + func() *big.Int { + val := new(big.Int) + val.SetUint64(^uint64(0)) // max uint64 + return val + }(), + } + + for i, originalValue := range testValues { + t.Run(fmt.Sprintf("round_trip_%d", i), func(t *testing.T) { + // Go big.Int -> protobuf BigInt -> Go big.Int + pbBigInt := intToPbBigInt(originalValue) + convertedValue := pbBigIntToInt(pbBigInt) + + // Handle nil case specially + if originalValue == nil { + assert.Nil(t, convertedValue, "nil should round-trip to nil") + } else { + assert.NotNil(t, convertedValue, "non-nil should round-trip to non-nil") + assert.Equal(t, originalValue.String(), convertedValue.String(), "round-trip conversion should preserve value") + assert.Equal(t, originalValue.Cmp(convertedValue), 0, "round-trip big.Int comparison should be equal") + } + }) + } +} + +// TestPbToBigIntRoundTrip tests round-trip conversion between protobuf BigInt and ccipocr3.BigInt +func TestPbToBigIntRoundTrip(t *testing.T) { + testValues := []ccipocr3.BigInt{ + ccipocr3.NewBigInt(big.NewInt(0)), + ccipocr3.NewBigInt(big.NewInt(1)), + ccipocr3.NewBigInt(big.NewInt(42)), + ccipocr3.NewBigInt(big.NewInt(255)), + ccipocr3.NewBigInt(big.NewInt(256)), + ccipocr3.NewBigInt(big.NewInt(65535)), + ccipocr3.NewBigInt(big.NewInt(65536)), + ccipocr3.NewBigInt(big.NewInt(1234567890)), + func() ccipocr3.BigInt { + val := new(big.Int) + val.SetString("999999999999999999999999999999", 10) + return ccipocr3.NewBigInt(val) + }(), + func() ccipocr3.BigInt { + val := new(big.Int) + val.SetUint64(^uint64(0)) // max uint64 + return ccipocr3.NewBigInt(val) + }(), + // Test nil value specially + ccipocr3.BigInt{Int: nil}, + } + + for i, originalValue := range testValues { + t.Run(fmt.Sprintf("round_trip_%d", i), func(t *testing.T) { + // ccipocr3.BigInt -> protobuf BigInt -> ccipocr3.BigInt + pbBigInt := intToPbBigInt(originalValue.Int) + convertedValue := pbToBigInt(pbBigInt) + + // Handle nil case specially + if originalValue.Int == nil { + assert.Nil(t, convertedValue.Int, "nil should round-trip to nil") + } else { + assert.NotNil(t, convertedValue.Int, "converted value should not be nil for non-nil input") + assert.Equal(t, originalValue.Int.String(), convertedValue.Int.String(), "round-trip conversion should preserve value") + assert.Equal(t, originalValue.Int.Cmp(convertedValue.Int), 0, "round-trip BigInt comparison should be equal") + } + }) + } +} + +// TestPbBigIntEdgeCases tests edge cases and error conditions +func TestPbBigIntEdgeCases(t *testing.T) { + t.Run("empty bytes should not panic", func(t *testing.T) { + input := &ccipocr3pb.BigInt{Value: []byte{}} + + // Should not panic + result1 := pbBigIntToInt(input) + result2 := pbToBigInt(input) + + assert.Equal(t, big.NewInt(0).String(), result1.String()) + assert.Equal(t, big.NewInt(0).String(), result2.Int.String()) + }) + + t.Run("single zero byte should equal zero", func(t *testing.T) { + input := &ccipocr3pb.BigInt{Value: []byte{0x00}} + + result1 := pbBigIntToInt(input) + result2 := pbToBigInt(input) + + assert.Equal(t, big.NewInt(0).String(), result1.String()) + assert.Equal(t, big.NewInt(0).String(), result2.Int.String()) + }) + + t.Run("multiple zero bytes should equal zero", func(t *testing.T) { + input := &ccipocr3pb.BigInt{Value: []byte{0x00, 0x00, 0x00, 0x00}} + + result1 := pbBigIntToInt(input) + result2 := pbToBigInt(input) + + assert.Equal(t, big.NewInt(0).String(), result1.String()) + assert.Equal(t, big.NewInt(0).String(), result2.Int.String()) + }) + + t.Run("large byte array should work correctly", func(t *testing.T) { + // Create a 64-byte array (512 bits) + bytes := make([]byte, 64) + bytes[0] = 0x01 // Set the most significant bit to 1 + + input := &ccipocr3pb.BigInt{Value: bytes} + + result1 := pbBigIntToInt(input) + result2 := pbToBigInt(input) + + expected := new(big.Int).SetBytes(bytes) + + assert.Equal(t, expected.String(), result1.String()) + assert.Equal(t, expected.String(), result2.Int.String()) + }) +} + +// TestPbBigIntConsistency tests that both functions handle the same inputs consistently +func TestPbBigIntConsistency(t *testing.T) { + testInputs := []*ccipocr3pb.BigInt{ + nil, + {Value: nil}, + {Value: []byte{}}, + {Value: []byte{0x00}}, + {Value: []byte{0x01}}, + {Value: []byte{0xFF}}, + {Value: []byte{0x01, 0x00}}, + {Value: []byte{0xFF, 0xFF}}, + {Value: big.NewInt(42).Bytes()}, + {Value: big.NewInt(1234567890).Bytes()}, + } + + for i, input := range testInputs { + t.Run(fmt.Sprintf("consistency_test_%d", i), func(t *testing.T) { + result1 := pbBigIntToInt(input) + result2 := pbToBigInt(input) + + // For non-nil inputs, both functions should produce equivalent numeric results + // (except pbToBigInt may preserve nil differently) + if input != nil { + if result2.Int != nil { + assert.Equal(t, result1.String(), result2.Int.String(), + "pbBigIntToInt and pbToBigInt should produce equivalent numeric results") + } + } + }) + } +} + +// TestTokenInfoConversion tests the TokenInfo conversion functions +func TestTokenInfoConversion(t *testing.T) { + testCases := []struct { + name string + info ccipocr3.TokenInfo + expected ccipocr3.TokenInfo + }{ + { + name: "complete TokenInfo", + info: ccipocr3.TokenInfo{ + AggregatorAddress: ccipocr3.UnknownEncodedAddress("0x1234567890123456789012345678901234567890"), + DeviationPPB: ccipocr3.NewBigInt(big.NewInt(1000000000)), // 1% + Decimals: 18, + }, + expected: ccipocr3.TokenInfo{ + AggregatorAddress: ccipocr3.UnknownEncodedAddress("0x1234567890123456789012345678901234567890"), + DeviationPPB: ccipocr3.NewBigInt(big.NewInt(1000000000)), + Decimals: 18, + }, + }, + { + name: "minimal TokenInfo", + info: ccipocr3.TokenInfo{ + AggregatorAddress: ccipocr3.UnknownEncodedAddress("0xabc"), + DeviationPPB: ccipocr3.NewBigInt(big.NewInt(1)), + Decimals: 6, + }, + expected: ccipocr3.TokenInfo{ + AggregatorAddress: ccipocr3.UnknownEncodedAddress("0xabc"), + DeviationPPB: ccipocr3.NewBigInt(big.NewInt(1)), + Decimals: 6, + }, + }, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + // Convert to protobuf and back + pbInfo := tokenInfoToPb(tc.info) + convertedInfo := pbToTokenInfo(pbInfo) + + assert.Equal(t, tc.expected.AggregatorAddress, convertedInfo.AggregatorAddress) + assert.Equal(t, tc.expected.DeviationPPB.String(), convertedInfo.DeviationPPB.String()) + assert.Equal(t, tc.expected.Decimals, convertedInfo.Decimals) + }) + } +} + +// TestTokenInfoMapConversion tests the TokenInfo map conversion functions +func TestTokenInfoMapConversion(t *testing.T) { + testMap := map[ccipocr3.UnknownEncodedAddress]ccipocr3.TokenInfo{ + "token1": { + AggregatorAddress: ccipocr3.UnknownEncodedAddress("0x1111111111111111111111111111111111111111"), + DeviationPPB: ccipocr3.NewBigInt(big.NewInt(2000000000)), // 2% + Decimals: 18, + }, + "token2": { + AggregatorAddress: ccipocr3.UnknownEncodedAddress("0x2222222222222222222222222222222222222222"), + DeviationPPB: ccipocr3.NewBigInt(big.NewInt(5000000000)), // 5% + Decimals: 6, + }, + } + + // Convert to protobuf and back + pbMap := tokenInfoMapToPb(testMap) + convertedMap := pbToTokenInfoMap(pbMap) + + assert.Len(t, convertedMap, 2) + + for token, expectedInfo := range testMap { + convertedInfo, exists := convertedMap[token] + assert.True(t, exists, "Token %s should exist in converted map", token) + assert.Equal(t, expectedInfo.AggregatorAddress, convertedInfo.AggregatorAddress) + assert.Equal(t, expectedInfo.DeviationPPB.String(), convertedInfo.DeviationPPB.String()) + assert.Equal(t, expectedInfo.Decimals, convertedInfo.Decimals) + } +} + +// TestTokenInfoMapNilHandling tests nil handling for TokenInfo map conversion +func TestTokenInfoMapNilHandling(t *testing.T) { + t.Run("nil map to protobuf", func(t *testing.T) { + result := tokenInfoMapToPb(nil) + assert.Nil(t, result) + }) + + t.Run("nil protobuf map to Go", func(t *testing.T) { + result := pbToTokenInfoMap(nil) + assert.Nil(t, result) + }) + + t.Run("empty map round-trip", func(t *testing.T) { + emptyMap := make(map[ccipocr3.UnknownEncodedAddress]ccipocr3.TokenInfo) + pbMap := tokenInfoMapToPb(emptyMap) + convertedMap := pbToTokenInfoMap(pbMap) + assert.NotNil(t, convertedMap) + assert.Len(t, convertedMap, 0) + }) +} diff --git a/pkg/loop/internal/relayer/pluginprovider/ext/ccipocr3/test/chain_accessor.go b/pkg/loop/internal/relayer/pluginprovider/ext/ccipocr3/test/chain_accessor.go index 32b9fe7ec..454220b7b 100644 --- a/pkg/loop/internal/relayer/pluginprovider/ext/ccipocr3/test/chain_accessor.go +++ b/pkg/loop/internal/relayer/pluginprovider/ext/ccipocr3/test/chain_accessor.go @@ -205,14 +205,14 @@ func ChainAccessor(lggr logger.Logger) staticChainAccessor { "sender3": 5, }, }, - chainFeePriceUpdates: map[ccipocr3.ChainSelector]ccipocr3.TimestampedBig{ + chainFeePriceUpdates: map[ccipocr3.ChainSelector]ccipocr3.TimestampedUnixBig{ ccipocr3.ChainSelector(1): { - Timestamp: testTime, - Value: ccipocr3.NewBigInt(big.NewInt(2000000000)), + Timestamp: uint32(testTime.Unix()), + Value: big.NewInt(2000000000), }, ccipocr3.ChainSelector(2): { - Timestamp: testTime.Add(time.Hour), - Value: ccipocr3.NewBigInt(big.NewInt(1800000000)), + Timestamp: uint32(testTime.Add(time.Hour).Unix()), + Value: big.NewInt(1800000000), }, }, latestPriceSeqNr: 42, @@ -294,7 +294,7 @@ type staticChainAccessorConfig struct { executedMessages map[ccipocr3.ChainSelector][]ccipocr3.SeqNum nextSeqNums map[ccipocr3.ChainSelector]ccipocr3.SeqNum nonces map[ccipocr3.ChainSelector]map[string]uint64 - chainFeePriceUpdates map[ccipocr3.ChainSelector]ccipocr3.TimestampedBig + chainFeePriceUpdates map[ccipocr3.ChainSelector]ccipocr3.TimestampedUnixBig latestPriceSeqNr uint64 messages []ccipocr3.Message latestMessageSeqNr ccipocr3.SeqNum @@ -351,12 +351,12 @@ func (s staticChainAccessor) Nonces(ctx context.Context, addresses map[ccipocr3. return s.nonces, nil } -func (s staticChainAccessor) GetChainFeePriceUpdate(ctx context.Context, chains []ccipocr3.ChainSelector) map[ccipocr3.ChainSelector]ccipocr3.TimestampedBig { - return s.chainFeePriceUpdates +func (s staticChainAccessor) GetChainFeePriceUpdate(ctx context.Context, chains []ccipocr3.ChainSelector) (map[ccipocr3.ChainSelector]ccipocr3.TimestampedUnixBig, error) { + return s.chainFeePriceUpdates, nil } -func (s staticChainAccessor) GetLatestPriceSeqNr(ctx context.Context) (uint64, error) { - return s.latestPriceSeqNr, nil +func (s staticChainAccessor) GetLatestPriceSeqNr(ctx context.Context) (ccipocr3.SeqNum, error) { + return ccipocr3.SeqNum(s.latestPriceSeqNr), nil } // SourceAccessor implementation @@ -381,6 +381,45 @@ func (s staticChainAccessor) GetFeeQuoterDestChainConfig(ctx context.Context, de return s.feeQuoterDestChainConfig, nil } +// USDCMessageReader implementation +func (s staticChainAccessor) MessagesByTokenID(ctx context.Context, source, dest ccipocr3.ChainSelector, tokens map[ccipocr3.MessageTokenID]ccipocr3.RampTokenAmount) (map[ccipocr3.MessageTokenID]ccipocr3.Bytes, error) { + // Return static test data for USDC messages + result := make(map[ccipocr3.MessageTokenID]ccipocr3.Bytes) + for tokenID := range tokens { + // Return some test message bytes + result[tokenID] = ccipocr3.Bytes(fmt.Sprintf("usdc-message-data-for-%s", tokenID.String())) + } + return result, nil +} + +// PriceReader implementation +func (s staticChainAccessor) GetFeedPricesUSD(ctx context.Context, tokens []ccipocr3.UnknownEncodedAddress, tokenInfo map[ccipocr3.UnknownEncodedAddress]ccipocr3.TokenInfo) (ccipocr3.TokenPriceMap, error) { + // Return static test prices + result := make(ccipocr3.TokenPriceMap) + for i, token := range tokens { + // Generate different prices for different tokens + price := big.NewInt(1000000 + int64(i)*100000) // $1.00, $1.10, $1.20, etc. in wei units + result[token] = ccipocr3.NewBigInt(price) + } + return result, nil +} + +func (s staticChainAccessor) GetFeeQuoterTokenUpdates(ctx context.Context, tokens []ccipocr3.UnknownEncodedAddress, chain ccipocr3.ChainSelector) (map[ccipocr3.UnknownEncodedAddress]ccipocr3.TimestampedUnixBig, error) { + // Return static test token updates + result := make(map[ccipocr3.UnknownEncodedAddress]ccipocr3.TimestampedUnixBig) + testTime := time.Date(2024, 1, 15, 12, 0, 0, 0, time.UTC) + + for i, token := range tokens { + // Generate different prices for different tokens + price := big.NewInt(2000000 + int64(i)*50000) // Different prices from GetFeedPricesUSD + result[token] = ccipocr3.TimestampedUnixBig{ + Timestamp: uint32(testTime.Add(time.Duration(i) * time.Minute).Unix()), // Different timestamps + Value: price, + } + } + return result, nil +} + // Evaluate implements ChainAccessorEvaluator. func (s staticChainAccessor) Evaluate(ctx context.Context, other ccipocr3.ChainAccessor) error { // Delegate to individual evaluation functions for better readability @@ -400,6 +439,9 @@ func (s staticChainAccessor) Evaluate(ctx context.Context, other ccipocr3.ChainA s.evaluateGetExpectedNextSequenceNumber, s.evaluateGetTokenPriceUSD, s.evaluateGetFeeQuoterDestChainConfig, + s.evaluateMessagesByTokenID, + s.evaluateGetFeedPricesUSD, + s.evaluateGetFeeQuoterTokenUpdates, } for _, evaluate := range evaluators { @@ -732,8 +774,14 @@ func (s staticChainAccessor) evaluateNonces(ctx context.Context, other ccipocr3. func (s staticChainAccessor) evaluateGetChainFeePriceUpdate(ctx context.Context, other ccipocr3.ChainAccessor) error { chains := []ccipocr3.ChainSelector{1, 2} - otherUpdates := other.GetChainFeePriceUpdate(ctx, chains) - myUpdates := s.GetChainFeePriceUpdate(ctx, chains) + otherUpdates, err := other.GetChainFeePriceUpdate(ctx, chains) + if err != nil { + return fmt.Errorf("GetChainFeePriceUpdate failed: %w", err) + } + myUpdates, err := s.GetChainFeePriceUpdate(ctx, chains) + if err != nil { + return fmt.Errorf("GetChainFeePriceUpdate failed: %w", err) + } if len(otherUpdates) != len(myUpdates) { return fmt.Errorf("GetChainFeePriceUpdate length mismatch: got %d, expected %d", len(otherUpdates), len(myUpdates)) } @@ -742,13 +790,13 @@ func (s staticChainAccessor) evaluateGetChainFeePriceUpdate(ctx context.Context, if !exists { return fmt.Errorf("GetChainFeePriceUpdate missing chain %d in other updates", chainSel) } - if otherUpdate.Value.Cmp(myUpdate.Value.Int) != 0 { + if otherUpdate.Value.Cmp(myUpdate.Value) != 0 { return fmt.Errorf("GetChainFeePriceUpdate chain %d Value mismatch: got %s, expected %s", chainSel, otherUpdate.Value.String(), myUpdate.Value.String()) } - if !otherUpdate.Timestamp.Equal(myUpdate.Timestamp) { - return fmt.Errorf("GetChainFeePriceUpdate chain %d Timestamp mismatch: got %s, expected %s", - chainSel, otherUpdate.Timestamp.Format(time.RFC3339), myUpdate.Timestamp.Format(time.RFC3339)) + if otherUpdate.Timestamp != myUpdate.Timestamp { + return fmt.Errorf("GetChainFeePriceUpdate chain %d Timestamp mismatch: got %d, expected %d", + chainSel, otherUpdate.Timestamp, myUpdate.Timestamp) } } return nil @@ -904,6 +952,108 @@ func (s staticChainAccessor) evaluateGetFeeQuoterDestChainConfig(ctx context.Con return nil } +func (s staticChainAccessor) evaluateMessagesByTokenID(ctx context.Context, other ccipocr3.ChainAccessor) error { + tokens := map[ccipocr3.MessageTokenID]ccipocr3.RampTokenAmount{ + ccipocr3.NewMessageTokenID(1, 0): { + SourcePoolAddress: ccipocr3.UnknownAddress("test-source-pool"), + DestTokenAddress: ccipocr3.UnknownAddress("test-dest-token"), + ExtraData: ccipocr3.Bytes("test-extra-data"), + Amount: ccipocr3.NewBigInt(big.NewInt(12345)), + }, + } + + otherMessages, err := other.MessagesByTokenID(ctx, ccipocr3.ChainSelector(1), ccipocr3.ChainSelector(2), tokens) + if err != nil { + return fmt.Errorf("MessagesByTokenID failed: %w", err) + } + myMessages, err := s.MessagesByTokenID(ctx, ccipocr3.ChainSelector(1), ccipocr3.ChainSelector(2), tokens) + if err != nil { + return fmt.Errorf("MessagesByTokenID failed: %w", err) + } + + if len(otherMessages) != len(myMessages) { + return fmt.Errorf("MessagesByTokenID length mismatch: got %d, expected %d", len(otherMessages), len(myMessages)) + } + + for tokenID, myMessage := range myMessages { + otherMessage, exists := otherMessages[tokenID] + if !exists { + return fmt.Errorf("MessagesByTokenID missing tokenID %s in other messages", tokenID.String()) + } + if string(otherMessage) != string(myMessage) { + return fmt.Errorf("MessagesByTokenID tokenID %s mismatch: got %s, expected %s", tokenID.String(), string(otherMessage), string(myMessage)) + } + } + return nil +} + +func (s staticChainAccessor) evaluateGetFeedPricesUSD(ctx context.Context, other ccipocr3.ChainAccessor) error { + tokens := []ccipocr3.UnknownEncodedAddress{"token1", "token2", "token3"} + tokenInfo := map[ccipocr3.UnknownEncodedAddress]ccipocr3.TokenInfo{ + "token1": { + AggregatorAddress: ccipocr3.UnknownEncodedAddress("0x1234567890123456789012345678901234567890"), + DeviationPPB: ccipocr3.NewBigInt(big.NewInt(1000000000)), // 1% + Decimals: 18, + }, + } + + otherPrices, err := other.GetFeedPricesUSD(ctx, tokens, tokenInfo) + if err != nil { + return fmt.Errorf("GetFeedPricesUSD failed: %w", err) + } + myPrices, err := s.GetFeedPricesUSD(ctx, tokens, tokenInfo) + if err != nil { + return fmt.Errorf("GetFeedPricesUSD failed: %w", err) + } + + if len(otherPrices) != len(myPrices) { + return fmt.Errorf("GetFeedPricesUSD length mismatch: got %d, expected %d", len(otherPrices), len(myPrices)) + } + + for token, myPrice := range myPrices { + otherPrice, exists := otherPrices[token] + if !exists { + return fmt.Errorf("GetFeedPricesUSD missing token %s in other prices", string(token)) + } + if otherPrice.Cmp(myPrice.Int) != 0 { + return fmt.Errorf("GetFeedPricesUSD token %s mismatch: got %s, expected %s", string(token), otherPrice.String(), myPrice.String()) + } + } + return nil +} + +func (s staticChainAccessor) evaluateGetFeeQuoterTokenUpdates(ctx context.Context, other ccipocr3.ChainAccessor) error { + tokens := []ccipocr3.UnknownEncodedAddress{"token1", "token2"} + chain := ccipocr3.ChainSelector(1) + + otherUpdates, err := other.GetFeeQuoterTokenUpdates(ctx, tokens, chain) + if err != nil { + return fmt.Errorf("GetFeeQuoterTokenUpdates failed: %w", err) + } + myUpdates, err := s.GetFeeQuoterTokenUpdates(ctx, tokens, chain) + if err != nil { + return fmt.Errorf("GetFeeQuoterTokenUpdates failed: %w", err) + } + + if len(otherUpdates) != len(myUpdates) { + return fmt.Errorf("GetFeeQuoterTokenUpdates length mismatch: got %d, expected %d", len(otherUpdates), len(myUpdates)) + } + + for token, myUpdate := range myUpdates { + otherUpdate, exists := otherUpdates[token] + if !exists { + return fmt.Errorf("GetFeeQuoterTokenUpdates missing token %s in other updates", string(token)) + } + if otherUpdate.Value.Cmp(myUpdate.Value) != 0 { + return fmt.Errorf("GetFeeQuoterTokenUpdates token %s value mismatch: got %s, expected %s", string(token), otherUpdate.Value.String(), myUpdate.Value.String()) + } + if otherUpdate.Timestamp != myUpdate.Timestamp { + return fmt.Errorf("GetFeeQuoterTokenUpdates token %s timestamp mismatch: got %d, expected %d", string(token), otherUpdate.Timestamp, myUpdate.Timestamp) + } + } + return nil +} + // AssertEqual implements ChainAccessorTester. func (s staticChainAccessor) AssertEqual(ctx context.Context, t *testing.T, other ccipocr3.ChainAccessor) { t.Run("ChainAccessor", func(t *testing.T) { diff --git a/pkg/loop/internal/relayer/pluginprovider/ext/ccipocr3/test/chain_accessor_test.go b/pkg/loop/internal/relayer/pluginprovider/ext/ccipocr3/test/chain_accessor_test.go index e70be47f4..afe704a5c 100644 --- a/pkg/loop/internal/relayer/pluginprovider/ext/ccipocr3/test/chain_accessor_test.go +++ b/pkg/loop/internal/relayer/pluginprovider/ext/ccipocr3/test/chain_accessor_test.go @@ -2,6 +2,7 @@ package test import ( "context" + "math/big" "testing" "time" @@ -73,14 +74,15 @@ func TestChainAccessor(t *testing.T) { }) t.Run("GetChainFeePriceUpdate", func(t *testing.T) { - updates := chainAccessor.GetChainFeePriceUpdate(ctx, []ccipocr3.ChainSelector{1, 2}) + updates, err := chainAccessor.GetChainFeePriceUpdate(ctx, []ccipocr3.ChainSelector{1, 2}) + assert.NoError(t, err) assert.NotNil(t, updates) }) t.Run("GetLatestPriceSeqNr", func(t *testing.T) { seqNr, err := chainAccessor.GetLatestPriceSeqNr(ctx) assert.NoError(t, err) - assert.Equal(t, uint64(42), seqNr) + assert.Equal(t, ccipocr3.SeqNum(42), seqNr) }) t.Run("MsgsBetweenSeqNums", func(t *testing.T) { @@ -112,6 +114,46 @@ func TestChainAccessor(t *testing.T) { assert.NoError(t, err) assert.NotNil(t, config) }) + + // USDCMessageReader tests + t.Run("MessagesByTokenID", func(t *testing.T) { + tokens := map[ccipocr3.MessageTokenID]ccipocr3.RampTokenAmount{ + ccipocr3.NewMessageTokenID(1, 0): { + SourcePoolAddress: ccipocr3.UnknownAddress("test-source-pool"), + DestTokenAddress: ccipocr3.UnknownAddress("test-dest-token"), + ExtraData: ccipocr3.Bytes("test-extra-data"), + Amount: ccipocr3.NewBigInt(big.NewInt(12345)), + }, + } + messages, err := chainAccessor.MessagesByTokenID(ctx, ccipocr3.ChainSelector(1), ccipocr3.ChainSelector(2), tokens) + assert.NoError(t, err) + assert.NotNil(t, messages) + assert.Len(t, messages, 1) + }) + + // PriceReader tests + t.Run("GetFeedPricesUSD", func(t *testing.T) { + tokens := []ccipocr3.UnknownEncodedAddress{"token1", "token2", "token3"} + tokenInfo := map[ccipocr3.UnknownEncodedAddress]ccipocr3.TokenInfo{ + "token1": { + AggregatorAddress: ccipocr3.UnknownEncodedAddress("0x1234567890123456789012345678901234567890"), + DeviationPPB: ccipocr3.NewBigInt(big.NewInt(1000000000)), // 1% + Decimals: 18, + }, + } + prices, err := chainAccessor.GetFeedPricesUSD(ctx, tokens, tokenInfo) + assert.NoError(t, err) + assert.NotNil(t, prices) + assert.Len(t, prices, 3) + }) + + t.Run("GetFeeQuoterTokenUpdates", func(t *testing.T) { + tokens := []ccipocr3.UnknownEncodedAddress{"token1", "token2"} + updates, err := chainAccessor.GetFeeQuoterTokenUpdates(ctx, tokens, ccipocr3.ChainSelector(1)) + assert.NoError(t, err) + assert.NotNil(t, updates) + assert.Len(t, updates, 2) + }) } func TestChainAccessorEvaluate(t *testing.T) { diff --git a/pkg/loop/internal/relayer/relayer.go b/pkg/loop/internal/relayer/relayer.go index 3c4b7f092..20b4dd795 100644 --- a/pkg/loop/internal/relayer/relayer.go +++ b/pkg/loop/internal/relayer/relayer.go @@ -31,6 +31,7 @@ import ( "github.com/smartcontractkit/chainlink-common/pkg/loop/internal/relayer/pluginprovider/ocr2" looptypes "github.com/smartcontractkit/chainlink-common/pkg/loop/internal/types" "github.com/smartcontractkit/chainlink-common/pkg/types" + ccipocr3types "github.com/smartcontractkit/chainlink-common/pkg/types/ccipocr3" "github.com/smartcontractkit/chainlink-common/pkg/types/core" ) @@ -289,23 +290,43 @@ func (r *relayerClient) NewLLOProvider(ctx context.Context, rargs types.RelayArg } func (r *relayerClient) NewCCIPProvider(ctx context.Context, cargs types.CCIPProviderArgs) (types.CCIPProvider, error) { - cc := r.NewClientConn("CCIPProvider", func(ctx context.Context) (uint32, net.Resources, error) { - reply, err := r.relayer.NewCCIPProvider(ctx, &pb.NewCCIPProviderRequest{ - CcipProviderArgs: &pb.CCIPProviderArgs{ - ExternalJobID: cargs.ExternalJobID[:], - ContractReaderConfig: cargs.ContractReaderConfig, - ChainWriterConfig: cargs.ChainWriterConfig, - OffRampAddress: cargs.OffRampAddress, - PluginType: cargs.PluginType, - }, - }) - if err != nil { - return 0, nil, err - } - return reply.CcipProviderID, nil, nil - }) + var provider types.CCIPProvider + + // Create client connection + clientConn := r.NewClientConn("CCIPProvider", + func(ctx context.Context) (uint32, net.Resources, error) { + // Convert synced contracts from existing provider to pb.SyncContract format + var pbSyncContracts []*pb.SyncContract + if ccipProvider, ok := provider.(*ccipocr3.CCIPProviderClient); ok { + syncedContracts := ccipProvider.GetSyncedContracts() + for contractName, contractAddress := range syncedContracts { + pbSyncContracts = append(pbSyncContracts, &pb.SyncContract{ + ContractName: contractName, + ContractAddress: contractAddress, + }) + } + r.Logger.Infow("Restoring synced contracts during refresh", "count", len(pbSyncContracts)) + } + reply, err := r.relayer.NewCCIPProvider(ctx, &pb.NewCCIPProviderRequest{ + CcipProviderArgs: &pb.CCIPProviderArgs{ + ExternalJobID: cargs.ExternalJobID[:], + ContractReaderConfig: cargs.ContractReaderConfig, + ChainWriterConfig: cargs.ChainWriterConfig, + OffRampAddress: cargs.OffRampAddress, + PluginType: cargs.PluginType, + SyncedContracts: pbSyncContracts, // TODO: call Sync() with these when constructing the accessor to resync + }, + }) + if err != nil { + return 0, nil, err + } + return reply.CcipProviderID, nil, nil + }, + ) + + provider = ccipocr3.NewCCIPProviderClient(r.WithName(cargs.ExternalJobID.String()).WithName("CCIPProviderClient"), clientConn) - return ccipocr3.NewCCIPProviderClient(r.WithName(cargs.ExternalJobID.String()).WithName("CCIPProviderClient"), cc), nil + return provider, nil } func (r *relayerClient) LatestHead(ctx context.Context) (types.Head, error) { @@ -735,6 +756,21 @@ func (r *relayerServer) NewCCIPProvider(ctx context.Context, request *pb.NewCCIP return nil, err } + // If synced contracts were provided, restore them in the chain accessor + if len(rargs.SyncedContracts) > 0 { + r.Logger.Infow("Restoring synced contracts in new provider", "count", len(rargs.SyncedContracts)) + chainAccessor := provider.ChainAccessor() + for _, syncContract := range rargs.SyncedContracts { + if err := chainAccessor.Sync(ctx, syncContract.ContractName, ccipocr3types.UnknownAddress(syncContract.ContractAddress)); err != nil { + r.Logger.Errorw("Failed to restore synced contract", + "contractName", syncContract.ContractName, + "contractAddress", syncContract.ContractAddress, + "err", err) + // Continue with other contracts even if one fails + } + } + } + const name = "CCIPProvider" id, _, err := r.ServeNew(name, func(s *grpc.Server) { ccipocr3.RegisterProviderServices(s, provider) diff --git a/pkg/types/ccipocr3/chainaccessor.go b/pkg/types/ccipocr3/chainaccessor.go index 64ae00811..764303929 100644 --- a/pkg/types/ccipocr3/chainaccessor.go +++ b/pkg/types/ccipocr3/chainaccessor.go @@ -3,7 +3,6 @@ package ccipocr3 import ( "context" "math/big" - "sort" "time" "github.com/smartcontractkit/chainlink-common/pkg/types/query/primitives" @@ -26,6 +25,8 @@ type ChainAccessor interface { AllAccessors SourceAccessor DestinationAccessor + USDCMessageReader + PriceReader } // AllAccessors contains functionality that is available to all types of accessors. @@ -133,7 +134,7 @@ type DestinationAccessor interface { // Access Type: Method(GetChainFeePriceUpdate) // Contract: FeeQuoter // Confidence: Unconfirmed - GetChainFeePriceUpdate(ctx context.Context, selectors []ChainSelector) map[ChainSelector]TimestampedBig + GetChainFeePriceUpdate(ctx context.Context, selectors []ChainSelector) (map[ChainSelector]TimestampedUnixBig, error) // GetLatestPriceSeqNr returns the latest price sequence number for the destination chain. // Not to confuse with the sequence number of the messages. This is the OCR sequence number. @@ -141,7 +142,7 @@ type DestinationAccessor interface { // Access Type: Method(GetLatestPriceSequenceNumber) // Contract: OffRamp // Confidence: Unconfirmed - GetLatestPriceSeqNr(ctx context.Context) (uint64, error) + GetLatestPriceSeqNr(ctx context.Context) (SeqNum, error) } type SourceAccessor interface { @@ -193,132 +194,32 @@ type SourceAccessor interface { GetFeeQuoterDestChainConfig(ctx context.Context, dest ChainSelector) (FeeQuoterDestChainConfig, error) } -//////////////////////////////////////////////////////////////// -// TODO: Find a better location for the types below this line // -// For the purpose of designing these interfaces, the // -// location is not critical. // -//////////////////////////////////////////////////////////////// - -// Random types. These are defined here mainly to bring focus to types which should -// probably be removed or replaced. - -type TimestampedBig struct { - Timestamp time.Time `json:"timestamp"` - Value BigInt `json:"value"` -} - -// TimestampedUnixBig Maps to on-chain struct -// https://github.com/smartcontractkit/chainlink/blob/37f3132362ec90b0b1c12fb1b69b9c16c46b399d/contracts/src/v0.8/ccip/libraries/Internal.sol#L43-L47 -// -//nolint:lll //url -type TimestampedUnixBig struct { - // Value in uint224, can contain several packed fields - Value *big.Int `json:"value"` - // Timestamp in seconds since epoch of most recent update - Timestamp uint32 `json:"timestamp"` -} - -func NewTimestampedBig(value int64, timestamp time.Time) TimestampedBig { - return TimestampedBig{ - Value: BigInt{Int: big.NewInt(value)}, - Timestamp: timestamp, - } -} - -func TimeStampedBigFromUnix(input TimestampedUnixBig) TimestampedBig { - return TimestampedBig{ - Value: NewBigInt(input.Value), - Timestamp: time.Unix(int64(input.Timestamp), 0), - } -} - -type CommitPluginReportWithMeta struct { - Report CommitPluginReport `json:"report"` - Timestamp time.Time `json:"timestamp"` - BlockNum uint64 `json:"blockNum"` -} - -type CommitReportsByConfidenceLevel struct { - Finalized []CommitPluginReportWithMeta `json:"finalized"` - Unfinalized []CommitPluginReportWithMeta `json:"unfinalized"` -} - -// ContractAddresses is a map of contract names across all chain selectors and their address. -// Currently only one contract per chain per name is supported. -type ContractAddresses map[string]map[ChainSelector]UnknownAddress - -func (ca ContractAddresses) Append(contract string, chain ChainSelector, address []byte) ContractAddresses { - resp := ca - if resp == nil { - resp = make(ContractAddresses) - } - if resp[contract] == nil { - resp[contract] = make(map[ChainSelector]UnknownAddress) - } - resp[contract][chain] = address - return resp -} - -// CurseInfo contains cursing information that are fetched from the rmn remote contract. -type CurseInfo struct { - // CursedSourceChains contains the cursed source chains. - CursedSourceChains map[ChainSelector]bool - // CursedDestination indicates that the destination chain is cursed. - CursedDestination bool - // GlobalCurse indicates that all chains are cursed. - GlobalCurse bool -} - -func (ci CurseInfo) NonCursedSourceChains(inputChains []ChainSelector) []ChainSelector { - if ci.GlobalCurse { - return nil - } - - sourceChains := make([]ChainSelector, 0, len(inputChains)) - for _, ch := range inputChains { - if !ci.CursedSourceChains[ch] { - sourceChains = append(sourceChains, ch) - } - } - sort.Slice(sourceChains, func(i, j int) bool { return sourceChains[i] < sourceChains[j] }) - - return sourceChains +// USDCMessageReader retrieves each of the CCTPv1 MessageSent event created +// when a ccipSend is made with USDC token transfer. The events are created +// when the USDC Token pool calls the 3rd party MessageTransmitter contract. +type USDCMessageReader interface { + MessagesByTokenID(ctx context.Context, + source, dest ChainSelector, + tokens map[MessageTokenID]RampTokenAmount, + ) (map[MessageTokenID]Bytes, error) } -// GlobalCurseSubject Defined as a const in RMNRemote.sol -// Docs of RMNRemote: -// An active curse on this subject will cause isCursed() and isCursed(bytes16) to return true. Use this subject -// for issues affecting all of CCIP chains, or pertaining to the chain that this contract is deployed on, instead of -// using the local chain selector as a subject. -var GlobalCurseSubject = [16]byte{ - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, -} - -// RemoteConfig contains the configuration fetched from the RMNRemote contract. -type RemoteConfig struct { - ContractAddress UnknownAddress `json:"contractAddress"` - ConfigDigest Bytes32 `json:"configDigest"` - Signers []RemoteSignerInfo `json:"signers"` - // F defines the max number of faulty RMN nodes; F+1 signers are required to verify a report. - FSign uint64 `json:"fSign"` // previously: MinSigners - ConfigVersion uint32 `json:"configVersion"` - RmnReportVersion Bytes32 `json:"rmnReportVersion"` // e.g., keccak256("RMN_V1_6_ANY2EVM_REPORT") -} - -func (r RemoteConfig) IsEmpty() bool { - // NOTE: contract address will always be present, since the code auto populates it - return r.ConfigDigest == (Bytes32{}) && - len(r.Signers) == 0 && - r.FSign == 0 && - r.ConfigVersion == 0 && - r.RmnReportVersion == (Bytes32{}) -} +type PriceReader interface { + // GetFeedPricesUSD returns the prices of the provided tokens in USD normalized to e18. + // 1 USDC = 1.00 USD per full token, each full token is 1e6 units -> 1 * 1e18 * 1e18 / 1e6 = 1e30 + // 1 ETH = 2,000 USD per full token, each full token is 1e18 units -> 2000 * 1e18 * 1e18 / 1e18 = 2_000e18 + // 1 LINK = 5.00 USD per full token, each full token is 1e18 units -> 5 * 1e18 * 1e18 / 1e18 = 5e18 + // The order of the returned prices corresponds to the order of the provided tokens. + GetFeedPricesUSD( + ctx context.Context, + tokens []UnknownEncodedAddress, + tokenInfo map[UnknownEncodedAddress]TokenInfo, + ) (TokenPriceMap, error) -// RemoteSignerInfo contains information about a signer from the RMNRemote contract. -type RemoteSignerInfo struct { - // The signer's onchain address, used to verify report signature - OnchainPublicKey UnknownAddress `json:"onchainPublicKey"` - // The index of the node in the RMN config - NodeIndex uint64 `json:"nodeIndex"` + // GetFeeQuoterTokenUpdates returns the latest token prices from the FeeQuoter on the specified chain + GetFeeQuoterTokenUpdates( + ctx context.Context, + tokens []UnknownEncodedAddress, + chain ChainSelector, + ) (map[UnknownEncodedAddress]TimestampedUnixBig, error) } diff --git a/pkg/types/ccipocr3/generic_types.go b/pkg/types/ccipocr3/generic_types.go index 40518e3f4..6564abc4d 100644 --- a/pkg/types/ccipocr3/generic_types.go +++ b/pkg/types/ccipocr3/generic_types.go @@ -1,12 +1,16 @@ package ccipocr3 import ( + "encoding/hex" "encoding/json" + "errors" "fmt" "math" "math/big" "sort" "strconv" + "strings" + "time" ) type TokenPrice struct { @@ -37,6 +41,43 @@ func NewTokenPrice(tokenID UnknownEncodedAddress, price *big.Int) TokenPrice { } } +type TokenInfo struct { + // AggregatorAddress is the address of the price feed TOKEN/USD aggregator on the feed chain. + AggregatorAddress UnknownEncodedAddress `json:"aggregatorAddress"` + + // DeviationPPB is the deviation in parts per billion that the price feed is allowed to deviate + // from the last written price on-chain before we write a new price. + DeviationPPB BigInt `json:"deviationPPB"` + + // Decimals is the number of decimals for the token (NOT the feed). + Decimals uint8 `json:"decimals"` +} + +func (a TokenInfo) Validate() error { + if a.AggregatorAddress == "" { + return errors.New("aggregatorAddress not set") + } + + // aggregator must be an ethereum address + decoded, err := hex.DecodeString(strings.ToLower(strings.TrimPrefix(string(a.AggregatorAddress), "0x"))) + if err != nil { + return fmt.Errorf("aggregatorAddress must be a valid ethereum address (i.e hex encoded 20 bytes): %w", err) + } + if len(decoded) != 20 { + return fmt.Errorf("aggregatorAddress must be a valid ethereum address, got %d bytes expected 20", len(decoded)) + } + + if a.DeviationPPB.Int.Cmp(big.NewInt(0)) <= 0 { + return errors.New("deviationPPB not set or negative, must be positive") + } + + if a.Decimals == 0 { + return fmt.Errorf("tokenDecimals can't be zero") + } + + return nil +} + type GasPriceChain struct { ChainSel ChainSelector `json:"chainSel"` GasPrice BigInt `json:"gasPrice"` @@ -270,3 +311,65 @@ type RampTokenAmount struct { // or hashing it. See Internal._hash(Any2EVMRampMessage) for more details as an example. DestExecData Bytes `json:"destExecData"` } + +// MessageTokenID is a unique identifier for a message token data (per chain selector). It's a composite key of +// the message sequence number and the token index within the message. It's used to easier identify token data for +// messages without having to deal with nested maps. +type MessageTokenID struct { + SeqNr SeqNum + Index int +} + +func NewMessageTokenID(seqNr SeqNum, index int) MessageTokenID { + return MessageTokenID{SeqNr: seqNr, Index: index} +} + +func (mti MessageTokenID) String() string { + return fmt.Sprintf("%d_%d", mti.SeqNr, mti.Index) +} + +type TimestampedBig struct { + Timestamp time.Time `json:"timestamp"` + Value BigInt `json:"value"` +} + +// TimestampedUnixBig Maps to on-chain struct +// https://github.com/smartcontractkit/chainlink/blob/37f3132362ec90b0b1c12fb1b69b9c16c46b399d/contracts/src/v0.8/ccip/libraries/Internal.sol#L43-L47 +// +//nolint:lll //url +type TimestampedUnixBig struct { + // Value in uint224, can contain several packed fields + Value *big.Int `json:"value"` + // Timestamp in seconds since epoch of most recent update + Timestamp uint32 `json:"timestamp"` +} + +func NewTimestampedBig(value int64, timestamp time.Time) TimestampedBig { + return TimestampedBig{ + Value: BigInt{Int: big.NewInt(value)}, + Timestamp: timestamp, + } +} + +func TimeStampedBigFromUnix(input TimestampedUnixBig) TimestampedBig { + return TimestampedBig{ + Value: NewBigInt(input.Value), + Timestamp: time.Unix(int64(input.Timestamp), 0), + } +} + +// ContractAddresses is a map of contract names across all chain selectors and their address. +// Currently only one contract per chain per name is supported. +type ContractAddresses map[string]map[ChainSelector]UnknownAddress + +func (ca ContractAddresses) Append(contract string, chain ChainSelector, address []byte) ContractAddresses { + resp := ca + if resp == nil { + resp = make(ContractAddresses) + } + if resp[contract] == nil { + resp[contract] = make(map[ChainSelector]UnknownAddress) + } + resp[contract][chain] = address + return resp +} diff --git a/pkg/types/ccipocr3/plugin_commit_types.go b/pkg/types/ccipocr3/plugin_commit_types.go index 3557fdbe3..2f68b69ad 100644 --- a/pkg/types/ccipocr3/plugin_commit_types.go +++ b/pkg/types/ccipocr3/plugin_commit_types.go @@ -4,6 +4,7 @@ import ( "bytes" "encoding/json" "fmt" + "time" ) // CommitPluginReport contains the necessary information to commit CCIP @@ -105,3 +106,14 @@ func DecodeCommitReportInfo(data []byte) (CommitReportInfo, error) { return CommitReportInfo{}, fmt.Errorf("unknown execute report info version (%d)", data[0]) } } + +type CommitPluginReportWithMeta struct { + Report CommitPluginReport `json:"report"` + Timestamp time.Time `json:"timestamp"` + BlockNum uint64 `json:"blockNum"` +} + +type CommitReportsByConfidenceLevel struct { + Finalized []CommitPluginReportWithMeta `json:"finalized"` + Unfinalized []CommitPluginReportWithMeta `json:"unfinalized"` +} diff --git a/pkg/types/ccipocr3/rmn_types.go b/pkg/types/ccipocr3/rmn_types.go index 8104d76ef..85c1ee236 100644 --- a/pkg/types/ccipocr3/rmn_types.go +++ b/pkg/types/ccipocr3/rmn_types.go @@ -1,5 +1,7 @@ package ccipocr3 +import "sort" + // RMNReport is the payload that is signed by the RMN nodes, transmitted and verified onchain. type RMNReport struct { ReportVersionDigest Bytes32 // e.g. keccak256("RMN_V1_6_ANY2EVM_REPORT") @@ -48,3 +50,67 @@ type RMNECDSASignature struct { R Bytes32 `json:"r"` S Bytes32 `json:"s"` } + +// CurseInfo contains cursing information that are fetched from the rmn remote contract. +type CurseInfo struct { + // CursedSourceChains contains the cursed source chains. + CursedSourceChains map[ChainSelector]bool + // CursedDestination indicates that the destination chain is cursed. + CursedDestination bool + // GlobalCurse indicates that all chains are cursed. + GlobalCurse bool +} + +func (ci CurseInfo) NonCursedSourceChains(inputChains []ChainSelector) []ChainSelector { + if ci.GlobalCurse { + return nil + } + + sourceChains := make([]ChainSelector, 0, len(inputChains)) + for _, ch := range inputChains { + if !ci.CursedSourceChains[ch] { + sourceChains = append(sourceChains, ch) + } + } + sort.Slice(sourceChains, func(i, j int) bool { return sourceChains[i] < sourceChains[j] }) + + return sourceChains +} + +// GlobalCurseSubject Defined as a const in RMNRemote.sol +// Docs of RMNRemote: +// An active curse on this subject will cause isCursed() and isCursed(bytes16) to return true. Use this subject +// for issues affecting all of CCIP chains, or pertaining to the chain that this contract is deployed on, instead of +// using the local chain selector as a subject. +var GlobalCurseSubject = [16]byte{ + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, +} + +// RemoteConfig contains the configuration fetched from the RMNRemote contract. +type RemoteConfig struct { + ContractAddress UnknownAddress `json:"contractAddress"` + ConfigDigest Bytes32 `json:"configDigest"` + Signers []RemoteSignerInfo `json:"signers"` + // F defines the max number of faulty RMN nodes; F+1 signers are required to verify a report. + FSign uint64 `json:"fSign"` // previously: MinSigners + ConfigVersion uint32 `json:"configVersion"` + RmnReportVersion Bytes32 `json:"rmnReportVersion"` // e.g., keccak256("RMN_V1_6_ANY2EVM_REPORT") +} + +func (r RemoteConfig) IsEmpty() bool { + // NOTE: contract address will always be present, since the code auto populates it + return r.ConfigDigest == (Bytes32{}) && + len(r.Signers) == 0 && + r.FSign == 0 && + r.ConfigVersion == 0 && + r.RmnReportVersion == (Bytes32{}) +} + +// RemoteSignerInfo contains information about a signer from the RMNRemote contract. +type RemoteSignerInfo struct { + // The signer's onchain address, used to verify report signature + OnchainPublicKey UnknownAddress `json:"onchainPublicKey"` + // The index of the node in the RMN config + NodeIndex uint64 `json:"nodeIndex"` +}