From 0b69927afc2c6f17dccd28a30924fb0d568d9be2 Mon Sep 17 00:00:00 2001 From: Dzmitry Hil Date: Wed, 17 Apr 2024 14:17:41 +0300 Subject: [PATCH] Add xrpl_rpc_decoding_errors_total metric and alert. (#206) --- infra/composer/prometheus/alert.rules | 8 ++ integration-tests/xrpl.go | 1 + integration-tests/xrpl/scanner_test.go | 2 + relayer/metrics/registry.go | 12 ++ relayer/runner/runner.go | 2 +- relayer/xrpl/rpc.go | 84 ++++++++++--- relayer/xrpl/rpc_mocks_test.go | 84 +++++++++++++ relayer/xrpl/rpc_test.go | 159 +++++++++++++++++++++++++ relayer/xrpl/scanner.go | 10 +- relayer/xrpl/scanner_mocks_test.go | 36 +++--- relayer/xrpl/scanner_test.go | 2 +- 11 files changed, 361 insertions(+), 39 deletions(-) create mode 100644 relayer/xrpl/rpc_mocks_test.go create mode 100644 relayer/xrpl/rpc_test.go diff --git a/infra/composer/prometheus/alert.rules b/infra/composer/prometheus/alert.rules index 9d4247dc..718cd403 100644 --- a/infra/composer/prometheus/alert.rules +++ b/infra/composer/prometheus/alert.rules @@ -90,3 +90,11 @@ groups: severity: "critical" annotations: description: "The bridge is halted" + + - alert: XRPL RPC decoding error + expr: xrpl_rpc_decoding_errors_total > 0 + for: 1s + labels: + severity: major + annotations: + description: "Found XRPL RPC decoding error" diff --git a/integration-tests/xrpl.go b/integration-tests/xrpl.go index 2acf974c..d15a187b 100644 --- a/integration-tests/xrpl.go +++ b/integration-tests/xrpl.go @@ -66,6 +66,7 @@ func NewXRPLChain(cfg XRPLChainConfig, log logger.Logger) (XRPLChain, error) { xrpl.DefaultRPCClientConfig(cfg.RPCAddress), log, http.NewRetryableClient(http.DefaultClientConfig()), + nil, ) signer := xrpl.NewKeyringTxSigner(kr) diff --git a/integration-tests/xrpl/scanner_test.go b/integration-tests/xrpl/scanner_test.go index a56949ab..1f7f0dec 100644 --- a/integration-tests/xrpl/scanner_test.go +++ b/integration-tests/xrpl/scanner_test.go @@ -43,6 +43,7 @@ func TestFullHistoryScanAccountTx(t *testing.T) { rpcClientConfig, chains.Log, http.NewRetryableClient(http.DefaultClientConfig()), + nil, ) // enable just historical scan @@ -97,6 +98,7 @@ func TestRecentHistoryScanAccountTx(t *testing.T) { rpcClientConfig, chains.Log, http.NewRetryableClient(http.DefaultClientConfig()), + nil, ) // update config to use recent scan only diff --git a/relayer/metrics/registry.go b/relayer/metrics/registry.go index b5ac0849..b781ffaf 100644 --- a/relayer/metrics/registry.go +++ b/relayer/metrics/registry.go @@ -23,6 +23,7 @@ const ( relayerActivityMetricName = "relayer_activity" xrplTokensCoreumSupplyMetricName = "xrpl_tokens_coreum_supply" xrplBridgeAccountReservesMetricName = "xrpl_bridge_account_reserves" + xrplRPCDecodingErrorCounterMetricName = "xrpl_rpc_decoding_errors_total" // XRPLCurrencyIssuerLabel is XRPL currency issuer label. XRPLCurrencyIssuerLabel = "xrpl_currency_issuer" @@ -59,6 +60,7 @@ type Registry struct { RelayerActivityGaugeVec *prometheus.GaugeVec XRPLTokensCoreumSupplyGaugeVec *prometheus.GaugeVec XRPLBridgeAccountReservesGauge prometheus.Gauge + XRPLRPCDecodingErrorCounter prometheus.Counter } // NewRegistry returns new metric registry. @@ -167,6 +169,10 @@ func NewRegistry() *Registry { Name: xrplBridgeAccountReservesMetricName, Help: "XRPL bridge account reserves", }), + XRPLRPCDecodingErrorCounter: prometheus.NewCounter(prometheus.CounterOpts{ + Name: xrplRPCDecodingErrorCounterMetricName, + Help: "XRPL RPC decoding error counter", + }), } } @@ -190,6 +196,7 @@ func (m *Registry) Register(registry prometheus.Registerer) error { m.RelayerActivityGaugeVec, m.XRPLTokensCoreumSupplyGaugeVec, m.XRPLBridgeAccountReservesGauge, + m.XRPLRPCDecodingErrorCounter, } for _, c := range collectors { @@ -221,3 +228,8 @@ func (m *Registry) SetXRPLAccountFullHistoryScanLedgerIndex(index float64) { func (m *Registry) SetMaliciousBehaviourKey(key string) { m.MaliciousBehaviourGaugeVec.WithLabelValues(key).Set(1) } + +// IncrementXRPLRPCDecodingErrorCounter increments XRPLRPCDecodingErrorCounter. +func (m *Registry) IncrementXRPLRPCDecodingErrorCounter() { + m.XRPLRPCDecodingErrorCounter.Inc() +} diff --git a/relayer/runner/runner.go b/relayer/runner/runner.go index 1ca9670f..a9b207ac 100644 --- a/relayer/runner/runner.go +++ b/relayer/runner/runner.go @@ -247,7 +247,7 @@ func NewComponents( retryableXRPLRPCHTTPClient := toolshttp.NewRetryableClient(toolshttp.RetryableClientConfig(cfg.XRPL.HTTPClient)) xrplRPCClientCfg := xrpl.RPCClientConfig(cfg.XRPL.RPC) - xrplRPCClient := xrpl.NewRPCClient(xrplRPCClientCfg, log, retryableXRPLRPCHTTPClient) + xrplRPCClient := xrpl.NewRPCClient(xrplRPCClientCfg, log, retryableXRPLRPCHTTPClient, metricsRegistry) coreumClientContextCfg := coreumchainclient.DefaultContextConfig() coreumClientContextCfg.TimeoutConfig.RequestTimeout = cfg.Coreum.Contract.RequestTimeout diff --git a/relayer/xrpl/rpc.go b/relayer/xrpl/rpc.go index e8fef5eb..7c578b26 100644 --- a/relayer/xrpl/rpc.go +++ b/relayer/xrpl/rpc.go @@ -18,6 +18,11 @@ import ( "github.com/CoreumFoundation/coreumbridge-xrpl/relayer/logger" ) +//go:generate mockgen -destination=rpc_mocks_test.go -package=xrpl_test . HTTPClient,RPCMetricRegistry + +// UnknownTransactionResultErrorText error text for the unexpected tx code. +const UnknownTransactionResultErrorText = "Unknown TransactionResult" + // ******************** RPC command request objects ******************** // RPCError is RPC error result. @@ -137,6 +142,13 @@ type AccountTxResult struct { Validated bool `json:"validated"` } +// AccountTxWithRawTxsResult is `account_tx` method result with json.RawMessage transactions. +type AccountTxWithRawTxsResult struct { + Marker map[string]any `json:"marker,omitempty"` + Transactions []json.RawMessage `json:"transactions,omitempty"` + Validated bool `json:"validated"` +} + // ServerStateValidatedLedger is the latest validated ledger from the server state. type ServerStateValidatedLedger struct { BaseFee uint32 `json:"base_fee"` @@ -194,12 +206,14 @@ type RipplePathFindResult struct { // ******************** RPC transport objects ******************** -type rpcRequest struct { +// RPCRequest is general RPC request. +type RPCRequest struct { Method string `json:"method"` Params []any `json:"params,omitempty"` } -type rpcResponse struct { +// RPCResponse is general RPC response. +type RPCResponse struct { Result any `json:"result"` } @@ -210,6 +224,11 @@ type HTTPClient interface { DoJSON(ctx context.Context, method, url string, reqBody any, resDecoder func([]byte) error) error } +// RPCMetricRegistry is rpc metric registry. +type RPCMetricRegistry interface { + IncrementXRPLRPCDecodingErrorCounter() +} + // RPCClientConfig defines the config for the RPCClient. type RPCClientConfig struct { URL string @@ -226,17 +245,24 @@ func DefaultRPCClientConfig(url string) RPCClientConfig { // RPCClient implement the XRPL RPC client. type RPCClient struct { - cfg RPCClientConfig - log logger.Logger - httpClient HTTPClient + cfg RPCClientConfig + log logger.Logger + httpClient HTTPClient + metricRegistry RPCMetricRegistry } // NewRPCClient returns new instance of the RPCClient. -func NewRPCClient(cfg RPCClientConfig, log logger.Logger, httpClient HTTPClient) *RPCClient { +func NewRPCClient( + cfg RPCClientConfig, + log logger.Logger, + httpClient HTTPClient, + metricRegistry RPCMetricRegistry, +) *RPCClient { return &RPCClient{ - cfg: cfg, - log: log, - httpClient: httpClient, + cfg: cfg, + log: log, + httpClient: httpClient, + metricRegistry: metricRegistry, } } @@ -353,6 +379,11 @@ func (c *RPCClient) Submit(ctx context.Context, tx rippledata.Transaction) (Subm } var result SubmitResult if err := c.callRPC(ctx, "submit", params, &result); err != nil { + if strings.Contains(err.Error(), UnknownTransactionResultErrorText) { + c.log.Error(ctx, "Failed to decode XRPL transaction result", zap.Error(err)) + c.metricRegistry.IncrementXRPLRPCDecodingErrorCounter() + } + return SubmitResult{}, err } @@ -400,12 +431,37 @@ func (c *RPCClient) AccountTx( Limit: c.cfg.PageLimit, Marker: marker, } - var result AccountTxResult + var result AccountTxWithRawTxsResult if err := c.callRPC(ctx, "account_tx", params, &result); err != nil { return AccountTxResult{}, err } - return result, nil + txs := make(rippledata.TransactionSlice, 0) + for i, rawTx := range result.Transactions { + var tx rippledata.TransactionWithMetaData + if err := json.Unmarshal(rawTx, &tx); err != nil { + c.log.Error( + ctx, + "Failed to decode json tx to rippledata.TransactionWithMetaData", + zap.Error(err), + zap.String("tx", string(rawTx)), + zap.Int("txIndex", i), + zap.String("account", account.String()), + zap.Int64("minLedger", minLedger), + zap.Int64("maxLedger", maxLedger), + zap.Any("marker", marker), + ) + c.metricRegistry.IncrementXRPLRPCDecodingErrorCounter() + continue + } + txs = append(txs, &tx) + } + + return AccountTxResult{ + Marker: result.Marker, + Transactions: txs, + Validated: result.Validated, + }, nil } // ServerState returns the server state information. @@ -455,7 +511,7 @@ func (c *RPCClient) RipplePathFind( } func (c *RPCClient) callRPC(ctx context.Context, method string, params, result any) error { - request := rpcRequest{ + request := RPCRequest{ Method: method, Params: []any{ params, @@ -465,7 +521,7 @@ func (c *RPCClient) callRPC(ctx context.Context, method string, params, result a err := c.httpClient.DoJSON(ctx, http.MethodPost, c.cfg.URL, request, func(resBytes []byte) error { c.log.Debug(ctx, "Received XRPL RPC result", zap.String("result", string(resBytes))) - errResponse := rpcResponse{ + errResponse := RPCResponse{ Result: &RPCError{}, } if err := json.Unmarshal(resBytes, &errResponse); err != nil { @@ -478,7 +534,7 @@ func (c *RPCClient) callRPC(ctx context.Context, method string, params, result a if errResult.Code != 0 || strings.TrimSpace(errResult.Name) != "" { return errResult } - response := rpcResponse{ + response := RPCResponse{ Result: result, } if err := json.Unmarshal(resBytes, &response); err != nil { diff --git a/relayer/xrpl/rpc_mocks_test.go b/relayer/xrpl/rpc_mocks_test.go new file mode 100644 index 00000000..079125a0 --- /dev/null +++ b/relayer/xrpl/rpc_mocks_test.go @@ -0,0 +1,84 @@ +// Code generated by MockGen. DO NOT EDIT. +// Source: github.com/CoreumFoundation/coreumbridge-xrpl/relayer/xrpl (interfaces: HTTPClient,RPCMetricRegistry) + +// Package xrpl_test is a generated GoMock package. +package xrpl_test + +import ( + context "context" + reflect "reflect" + + gomock "github.com/golang/mock/gomock" +) + +// MockHTTPClient is a mock of HTTPClient interface. +type MockHTTPClient struct { + ctrl *gomock.Controller + recorder *MockHTTPClientMockRecorder +} + +// MockHTTPClientMockRecorder is the mock recorder for MockHTTPClient. +type MockHTTPClientMockRecorder struct { + mock *MockHTTPClient +} + +// NewMockHTTPClient creates a new mock instance. +func NewMockHTTPClient(ctrl *gomock.Controller) *MockHTTPClient { + mock := &MockHTTPClient{ctrl: ctrl} + mock.recorder = &MockHTTPClientMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use. +func (m *MockHTTPClient) EXPECT() *MockHTTPClientMockRecorder { + return m.recorder +} + +// DoJSON mocks base method. +func (m *MockHTTPClient) DoJSON(arg0 context.Context, arg1, arg2 string, arg3 interface{}, arg4 func([]byte) error) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "DoJSON", arg0, arg1, arg2, arg3, arg4) + ret0, _ := ret[0].(error) + return ret0 +} + +// DoJSON indicates an expected call of DoJSON. +func (mr *MockHTTPClientMockRecorder) DoJSON(arg0, arg1, arg2, arg3, arg4 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DoJSON", reflect.TypeOf((*MockHTTPClient)(nil).DoJSON), arg0, arg1, arg2, arg3, arg4) +} + +// MockRPCMetricRegistry is a mock of RPCMetricRegistry interface. +type MockRPCMetricRegistry struct { + ctrl *gomock.Controller + recorder *MockRPCMetricRegistryMockRecorder +} + +// MockRPCMetricRegistryMockRecorder is the mock recorder for MockRPCMetricRegistry. +type MockRPCMetricRegistryMockRecorder struct { + mock *MockRPCMetricRegistry +} + +// NewMockRPCMetricRegistry creates a new mock instance. +func NewMockRPCMetricRegistry(ctrl *gomock.Controller) *MockRPCMetricRegistry { + mock := &MockRPCMetricRegistry{ctrl: ctrl} + mock.recorder = &MockRPCMetricRegistryMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use. +func (m *MockRPCMetricRegistry) EXPECT() *MockRPCMetricRegistryMockRecorder { + return m.recorder +} + +// IncrementXRPLRPCDecodingErrorCounter mocks base method. +func (m *MockRPCMetricRegistry) IncrementXRPLRPCDecodingErrorCounter() { + m.ctrl.T.Helper() + m.ctrl.Call(m, "IncrementXRPLRPCDecodingErrorCounter") +} + +// IncrementXRPLRPCDecodingErrorCounter indicates an expected call of IncrementXRPLRPCDecodingErrorCounter. +func (mr *MockRPCMetricRegistryMockRecorder) IncrementXRPLRPCDecodingErrorCounter() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "IncrementXRPLRPCDecodingErrorCounter", reflect.TypeOf((*MockRPCMetricRegistry)(nil).IncrementXRPLRPCDecodingErrorCounter)) +} diff --git a/relayer/xrpl/rpc_test.go b/relayer/xrpl/rpc_test.go new file mode 100644 index 00000000..2621362f --- /dev/null +++ b/relayer/xrpl/rpc_test.go @@ -0,0 +1,159 @@ +package xrpl_test + +import ( + "context" + "encoding/json" + "testing" + + "github.com/golang/mock/gomock" + rippledata "github.com/rubblelabs/ripple/data" + "github.com/stretchr/testify/require" + + "github.com/CoreumFoundation/coreumbridge-xrpl/relayer/logger" + "github.com/CoreumFoundation/coreumbridge-xrpl/relayer/xrpl" +) + +func TestRPCClient_Submit(t *testing.T) { + ctx := context.Background() + + ctrl := gomock.NewController(t) + defer ctrl.Finish() + logMock := logger.NewAnyLogMock(ctrl) + httpClientMock := NewMockHTTPClient(ctrl) + metricRegistry := NewMockRPCMetricRegistry(ctrl) + + var txHash rippledata.Hash256 + copy(txHash[:], "1") + tx := &rippledata.TransactionWithMetaData{ + LedgerSequence: 1, + Transaction: &rippledata.Payment{ + Amount: rippledata.Amount{ + Value: &rippledata.Value{}, + }, + TxBase: rippledata.TxBase{ + Hash: txHash, + }, + }, + } + + rpcResult, err := json.Marshal( + xrpl.RPCResponse{ + Result: json.RawMessage(` + { + "engine_result": "UnexpectedCode", + "engine_result_code": 123456789, + "engine_result_message": "The transaction was applied. Only final in a validated ledger.", + "tx_blob": "data", + "tx_json": { + "Data": "data" + } + }`, + ), + }, + ) + require.NoError(t, err) + + httpClientMock.EXPECT().DoJSON(ctx, gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).DoAndReturn( + func( + ctx context.Context, + method, url string, + reqBody any, + resDecoder func([]byte) error, + ) error { + return resDecoder(rpcResult) + }, + ) + + logMock.EXPECT().Error( + gomock.Any(), gomock.Any(), gomock.Any(), + ) + + metricRegistry.EXPECT().IncrementXRPLRPCDecodingErrorCounter() + + rpcClient := xrpl.NewRPCClient(xrpl.DefaultRPCClientConfig(""), logMock, httpClientMock, metricRegistry) + _, err = rpcClient.Submit(ctx, tx) + require.Error(t, err) + require.ErrorContains(t, err, xrpl.UnknownTransactionResultErrorText) +} + +func TestRPCClient_AccountTx(t *testing.T) { + ctx := context.Background() + + ctrl := gomock.NewController(t) + defer ctrl.Finish() + logMock := logger.NewAnyLogMock(ctrl) + httpClientMock := NewMockHTTPClient(ctrl) + metricRegistry := NewMockRPCMetricRegistry(ctrl) + + var txHash1 rippledata.Hash256 + copy(txHash1[:], "1") + tx1 := &rippledata.TransactionWithMetaData{ + LedgerSequence: 1, + Transaction: &rippledata.Payment{ + Amount: rippledata.Amount{ + Value: &rippledata.Value{}, + }, + TxBase: rippledata.TxBase{ + Hash: txHash1, + }, + }, + } + tx1JSON, err := json.Marshal(tx1) + require.NoError(t, err) + + var txHash2 rippledata.Hash256 + copy(txHash2[:], "2") + tx2 := &rippledata.TransactionWithMetaData{ + LedgerSequence: 2, + Transaction: &rippledata.Payment{ + Amount: rippledata.Amount{ + Value: &rippledata.Value{}, + }, + TxBase: rippledata.TxBase{ + Hash: txHash2, + }, + }, + } + tx2JSON, err := json.Marshal(tx2) + require.NoError(t, err) + + rpcResult, err := json.Marshal( + xrpl.RPCResponse{ + Result: xrpl.AccountTxWithRawTxsResult{ + Marker: nil, + Transactions: []json.RawMessage{ + // the json in the middle is invalid + tx1JSON, json.RawMessage(`{"x": "y"}`), tx2JSON, + }, + Validated: true, + }, + }, + ) + require.NoError(t, err) + + httpClientMock.EXPECT().DoJSON(ctx, gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).DoAndReturn( + func( + ctx context.Context, + method, url string, + reqBody any, + resDecoder func([]byte) error, + ) error { + return resDecoder(rpcResult) + }, + ) + + logMock.EXPECT().Error( + gomock.Any(), gomock.Any(), gomock.Any(), + gomock.Any(), gomock.Any(), gomock.Any(), + gomock.Any(), gomock.Any(), gomock.Any(), + ) + + metricRegistry.EXPECT().IncrementXRPLRPCDecodingErrorCounter() + + rpcClient := xrpl.NewRPCClient(xrpl.DefaultRPCClientConfig(""), logMock, httpClientMock, metricRegistry) + txRes, err := rpcClient.AccountTx(ctx, rippledata.Account{}, -1, -1, nil) + require.NoError(t, err) + require.Len(t, txRes.Transactions, 2) + require.Equal(t, tx1.LedgerSequence, txRes.Transactions[0].LedgerSequence) + require.Equal(t, tx2.LedgerSequence, txRes.Transactions[1].LedgerSequence) +} diff --git a/relayer/xrpl/scanner.go b/relayer/xrpl/scanner.go index f216cf6e..ae943bb4 100644 --- a/relayer/xrpl/scanner.go +++ b/relayer/xrpl/scanner.go @@ -12,10 +12,10 @@ import ( "github.com/CoreumFoundation/coreumbridge-xrpl/relayer/logger" ) -//go:generate mockgen -destination=scanner_mocks_test.go -package=xrpl_test . RPCTxProvider,MetricRegistry +//go:generate mockgen -destination=scanner_mocks_test.go -package=xrpl_test . RPCTxProvider,ScannerMetricRegistry -// MetricRegistry is metric registry. -type MetricRegistry interface { +// ScannerMetricRegistry is scanner metric registry. +type ScannerMetricRegistry interface { SetXRPLAccountRecentHistoryScanLedgerIndex(index float64) SetXRPLAccountFullHistoryScanLedgerIndex(index float64) } @@ -65,7 +65,7 @@ type AccountScanner struct { cfg AccountScannerConfig log logger.Logger rpcTxProvider RPCTxProvider - metricRegistry MetricRegistry + metricRegistry ScannerMetricRegistry } // NewAccountScanner returns a nw instance of the AccountScanner. @@ -73,7 +73,7 @@ func NewAccountScanner( cfg AccountScannerConfig, log logger.Logger, rpcTxProvider RPCTxProvider, - metricRegistry MetricRegistry, + metricRegistry ScannerMetricRegistry, ) *AccountScanner { return &AccountScanner{ cfg: cfg, diff --git a/relayer/xrpl/scanner_mocks_test.go b/relayer/xrpl/scanner_mocks_test.go index 30770534..92c2edfe 100644 --- a/relayer/xrpl/scanner_mocks_test.go +++ b/relayer/xrpl/scanner_mocks_test.go @@ -1,5 +1,5 @@ // Code generated by MockGen. DO NOT EDIT. -// Source: github.com/CoreumFoundation/coreumbridge-xrpl/relayer/xrpl (interfaces: RPCTxProvider,MetricRegistry) +// Source: github.com/CoreumFoundation/coreumbridge-xrpl/relayer/xrpl (interfaces: RPCTxProvider,ScannerMetricRegistry) // Package xrpl_test is a generated GoMock package. package xrpl_test @@ -67,49 +67,49 @@ func (mr *MockRPCTxProviderMockRecorder) LedgerCurrent(arg0 interface{}) *gomock return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "LedgerCurrent", reflect.TypeOf((*MockRPCTxProvider)(nil).LedgerCurrent), arg0) } -// MockMetricRegistry is a mock of MetricRegistry interface. -type MockMetricRegistry struct { +// MockScannerMetricRegistry is a mock of ScannerMetricRegistry interface. +type MockScannerMetricRegistry struct { ctrl *gomock.Controller - recorder *MockMetricRegistryMockRecorder + recorder *MockScannerMetricRegistryMockRecorder } -// MockMetricRegistryMockRecorder is the mock recorder for MockMetricRegistry. -type MockMetricRegistryMockRecorder struct { - mock *MockMetricRegistry +// MockScannerMetricRegistryMockRecorder is the mock recorder for MockScannerMetricRegistry. +type MockScannerMetricRegistryMockRecorder struct { + mock *MockScannerMetricRegistry } -// NewMockMetricRegistry creates a new mock instance. -func NewMockMetricRegistry(ctrl *gomock.Controller) *MockMetricRegistry { - mock := &MockMetricRegistry{ctrl: ctrl} - mock.recorder = &MockMetricRegistryMockRecorder{mock} +// NewMockScannerMetricRegistry creates a new mock instance. +func NewMockScannerMetricRegistry(ctrl *gomock.Controller) *MockScannerMetricRegistry { + mock := &MockScannerMetricRegistry{ctrl: ctrl} + mock.recorder = &MockScannerMetricRegistryMockRecorder{mock} return mock } // EXPECT returns an object that allows the caller to indicate expected use. -func (m *MockMetricRegistry) EXPECT() *MockMetricRegistryMockRecorder { +func (m *MockScannerMetricRegistry) EXPECT() *MockScannerMetricRegistryMockRecorder { return m.recorder } // SetXRPLAccountFullHistoryScanLedgerIndex mocks base method. -func (m *MockMetricRegistry) SetXRPLAccountFullHistoryScanLedgerIndex(arg0 float64) { +func (m *MockScannerMetricRegistry) SetXRPLAccountFullHistoryScanLedgerIndex(arg0 float64) { m.ctrl.T.Helper() m.ctrl.Call(m, "SetXRPLAccountFullHistoryScanLedgerIndex", arg0) } // SetXRPLAccountFullHistoryScanLedgerIndex indicates an expected call of SetXRPLAccountFullHistoryScanLedgerIndex. -func (mr *MockMetricRegistryMockRecorder) SetXRPLAccountFullHistoryScanLedgerIndex(arg0 interface{}) *gomock.Call { +func (mr *MockScannerMetricRegistryMockRecorder) SetXRPLAccountFullHistoryScanLedgerIndex(arg0 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetXRPLAccountFullHistoryScanLedgerIndex", reflect.TypeOf((*MockMetricRegistry)(nil).SetXRPLAccountFullHistoryScanLedgerIndex), arg0) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetXRPLAccountFullHistoryScanLedgerIndex", reflect.TypeOf((*MockScannerMetricRegistry)(nil).SetXRPLAccountFullHistoryScanLedgerIndex), arg0) } // SetXRPLAccountRecentHistoryScanLedgerIndex mocks base method. -func (m *MockMetricRegistry) SetXRPLAccountRecentHistoryScanLedgerIndex(arg0 float64) { +func (m *MockScannerMetricRegistry) SetXRPLAccountRecentHistoryScanLedgerIndex(arg0 float64) { m.ctrl.T.Helper() m.ctrl.Call(m, "SetXRPLAccountRecentHistoryScanLedgerIndex", arg0) } // SetXRPLAccountRecentHistoryScanLedgerIndex indicates an expected call of SetXRPLAccountRecentHistoryScanLedgerIndex. -func (mr *MockMetricRegistryMockRecorder) SetXRPLAccountRecentHistoryScanLedgerIndex(arg0 interface{}) *gomock.Call { +func (mr *MockScannerMetricRegistryMockRecorder) SetXRPLAccountRecentHistoryScanLedgerIndex(arg0 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetXRPLAccountRecentHistoryScanLedgerIndex", reflect.TypeOf((*MockMetricRegistry)(nil).SetXRPLAccountRecentHistoryScanLedgerIndex), arg0) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetXRPLAccountRecentHistoryScanLedgerIndex", reflect.TypeOf((*MockScannerMetricRegistry)(nil).SetXRPLAccountRecentHistoryScanLedgerIndex), arg0) } diff --git a/relayer/xrpl/scanner_test.go b/relayer/xrpl/scanner_test.go index 5bda421e..196b86de 100644 --- a/relayer/xrpl/scanner_test.go +++ b/relayer/xrpl/scanner_test.go @@ -221,7 +221,7 @@ func TestAccountScanner_ScanTxs(t *testing.T) { logMock.EXPECT().Error(gomock.Any(), gomock.Any(), gomock.Any()) rpcTxProvider := tt.rpcTxProvider(ctrl) - metricRegistryMock := NewMockMetricRegistry(ctrl) + metricRegistryMock := NewMockScannerMetricRegistry(ctrl) metricRegistryMock.EXPECT().SetXRPLAccountRecentHistoryScanLedgerIndex(gomock.Any()).AnyTimes() metricRegistryMock.EXPECT().SetXRPLAccountFullHistoryScanLedgerIndex(gomock.Any()).AnyTimes()