diff --git a/chain_capabilities/stellar/actions/actions.go b/chain_capabilities/stellar/actions/actions.go index 363632e8f..bfc2b50db 100644 --- a/chain_capabilities/stellar/actions/actions.go +++ b/chain_capabilities/stellar/actions/actions.go @@ -36,16 +36,15 @@ import ( // Stellar implements the CRE capability actions for the Stellar chain. type Stellar struct { types.StellarService - handler chainconsensus.RequestHandler - lggr logger.SugaredLogger - messageBuilder *monitoring.MessageBuilder - beholderProcessor beholder.ProtoProcessor - chainSelector uint64 - forwarderClient CREForwarderClient - forwarderLookbackLedgers int64 - reportSizeLimit limits.BoundLimiter[commoncfg.Size] - maxResourceFeeLimit limits.BoundLimiter[uint64] - transmissionScheduler ts.TransmissionScheduler + handler chainconsensus.RequestHandler + lggr logger.SugaredLogger + messageBuilder *monitoring.MessageBuilder + beholderProcessor beholder.ProtoProcessor + chainSelector uint64 + forwarderClient CREForwarderClient + reportSizeLimit limits.BoundLimiter[commoncfg.Size] + maxResourceFeeLimit limits.BoundLimiter[uint64] + transmissionScheduler ts.TransmissionScheduler } func NewStellar( @@ -63,17 +62,22 @@ func NewStellar( if service == nil { return nil, fmt.Errorf("stellar service is required") } + if forwarderLookbackLedgers < 0 { + return nil, fmt.Errorf("forwarder lookback ledgers must be non-negative") + } + if forwarderLookbackLedgers == 0 { + forwarderLookbackLedgers = DefaultForwarderLookbackLedgers + } st := &Stellar{ - StellarService: service, - handler: handler, - lggr: logger.Sugared(lggr), - messageBuilder: messageBuilder, - beholderProcessor: beholderProcessor, - chainSelector: chainSelector, - forwarderClient: newForwarderClient(service, lggr, forwarderAddress, forwarderLookbackLedgers), - forwarderLookbackLedgers: forwarderLookbackLedgers, - transmissionScheduler: transmissionScheduler, + StellarService: service, + handler: handler, + lggr: logger.Sugared(lggr), + messageBuilder: messageBuilder, + beholderProcessor: beholderProcessor, + chainSelector: chainSelector, + forwarderClient: newForwarderClient(service, lggr, forwarderAddress, forwarderLookbackLedgers), + transmissionScheduler: transmissionScheduler, } return st, st.initLimiters(limitsFactory) } diff --git a/chain_capabilities/stellar/actions/actions_test.go b/chain_capabilities/stellar/actions/actions_test.go index b8fa18d0b..6a1bf063e 100644 --- a/chain_capabilities/stellar/actions/actions_test.go +++ b/chain_capabilities/stellar/actions/actions_test.go @@ -142,6 +142,26 @@ func TestNewStellar(t *testing.T) { require.NotNil(t, st) require.NoError(t, st.Close()) }) + + t.Run("negative forwarder lookback ledgers", func(t *testing.T) { + t.Parallel() + lggr := logger.Test(t) + svc := mocks.NewStellarService(t) + _, err := NewStellar( + svc, + "CDLZFC3SYJYDZT7K67VZ75HPJVIEUVNIXF47ZG2FB2RMQQVU2HHGCYSC", + -1, + lggr, + limits.Factory{Logger: lggr}, + ts.TransmissionScheduler{}, + 1, + testConsensusHandler{handle: runVolatileHashableHandle}, + monitoring.NewMessageBuilder(types.ChainInfo{}, capabilities.CapabilityInfo{}, ""), + nopBeholderProcessor{}, + ) + require.Error(t, err) + require.Contains(t, err.Error(), "forwarder lookback ledgers must be non-negative") + }) } func TestGetLatestLedger(t *testing.T) { diff --git a/chain_capabilities/stellar/actions/write_report.go b/chain_capabilities/stellar/actions/write_report.go index c9c4b713d..f8feb9080 100644 --- a/chain_capabilities/stellar/actions/write_report.go +++ b/chain_capabilities/stellar/actions/write_report.go @@ -35,16 +35,15 @@ const ( ) type writeReport struct { - service types.StellarService - forwarderClient CREForwarderClient - lggr logger.SugaredLogger - forwarderLookbackLedgers int64 - chainSelector uint64 - reportSizeLimit limits.BoundLimiter[commoncfg.Size] - maxResourceFeeLimit limits.BoundLimiter[uint64] - transmissionScheduler ts.TransmissionScheduler - messageBuilder *monitoring.MessageBuilder - beholderProcessor beholder.ProtoProcessor + service types.StellarService + forwarderClient CREForwarderClient + lggr logger.SugaredLogger + chainSelector uint64 + reportSizeLimit limits.BoundLimiter[commoncfg.Size] + maxResourceFeeLimit limits.BoundLimiter[uint64] + transmissionScheduler ts.TransmissionScheduler + messageBuilder *monitoring.MessageBuilder + beholderProcessor beholder.ProtoProcessor } func (s *Stellar) WriteReport( @@ -95,16 +94,15 @@ func (s *Stellar) executeWriteReport( telemetryContext monitoring.TelemetryContext, ) (*stellarcap.WriteReportReply, capabilities.ResponseMetadata, error) { wr := &writeReport{ - service: s.StellarService, - forwarderClient: s.forwarderClient, - lggr: s.messageBuilder.RequestLggr(s.lggr, telemetryContext), - forwarderLookbackLedgers: s.forwarderLookbackLedgers, - chainSelector: s.chainSelector, - reportSizeLimit: s.reportSizeLimit, - maxResourceFeeLimit: s.maxResourceFeeLimit, - transmissionScheduler: s.transmissionScheduler, - messageBuilder: s.messageBuilder, - beholderProcessor: s.beholderProcessor, + service: s.StellarService, + forwarderClient: s.forwarderClient, + lggr: s.messageBuilder.RequestLggr(s.lggr, telemetryContext), + chainSelector: s.chainSelector, + reportSizeLimit: s.reportSizeLimit, + maxResourceFeeLimit: s.maxResourceFeeLimit, + transmissionScheduler: s.transmissionScheduler, + messageBuilder: s.messageBuilder, + beholderProcessor: s.beholderProcessor, } return wr.execute(ctx, request, metadata, telemetryContext) } diff --git a/chain_capabilities/stellar/actions/write_report_test.go b/chain_capabilities/stellar/actions/write_report_test.go index 62d3ccd6f..7c073e216 100644 --- a/chain_capabilities/stellar/actions/write_report_test.go +++ b/chain_capabilities/stellar/actions/write_report_test.go @@ -74,15 +74,14 @@ func newWriteReportHelper(t *testing.T) *writeReportHelper { myPeerID, []p2ptypes.PeerID{myPeerID}, 100*time.Millisecond, 0, lggr) s := &Stellar{ - StellarService: mockSvc, - lggr: logger.Sugared(lggr), - chainSelector: testWRChainSelector, - forwarderClient: newForwarderClient(mockSvc, lggr, testForwarderAddress, 100), - forwarderLookbackLedgers: 100, - transmissionScheduler: scheduler, - messageBuilder: monitoring.NewMessageBuilder(types.ChainInfo{}, capabilities.CapabilityInfo{}, ""), - beholderProcessor: nopBeholderProcessor{}, - handler: testConsensusHandler{handle: runVolatileHashableHandle}, + StellarService: mockSvc, + lggr: logger.Sugared(lggr), + chainSelector: testWRChainSelector, + forwarderClient: newForwarderClient(mockSvc, lggr, testForwarderAddress, 100), + transmissionScheduler: scheduler, + messageBuilder: monitoring.NewMessageBuilder(types.ChainInfo{}, capabilities.CapabilityInfo{}, ""), + beholderProcessor: nopBeholderProcessor{}, + handler: testConsensusHandler{handle: runVolatileHashableHandle}, } require.NoError(t, s.initLimiters(limits.Factory{Logger: lggr})) return &writeReportHelper{svc: mockSvc, stellar: s} @@ -1433,15 +1432,14 @@ func newQueuedWriteReportHelper(t *testing.T) *writeReportHelper { lggr, ) s := &Stellar{ - StellarService: mockSvc, - lggr: logger.Sugared(lggr), - chainSelector: testWRChainSelector, - forwarderClient: newForwarderClient(mockSvc, lggr, testForwarderAddress, 100), - forwarderLookbackLedgers: 100, - transmissionScheduler: scheduler, - messageBuilder: monitoring.NewMessageBuilder(types.ChainInfo{}, capabilities.CapabilityInfo{}, ""), - beholderProcessor: nopBeholderProcessor{}, - handler: testConsensusHandler{handle: runVolatileHashableHandle}, + StellarService: mockSvc, + lggr: logger.Sugared(lggr), + chainSelector: testWRChainSelector, + forwarderClient: newForwarderClient(mockSvc, lggr, testForwarderAddress, 100), + transmissionScheduler: scheduler, + messageBuilder: monitoring.NewMessageBuilder(types.ChainInfo{}, capabilities.CapabilityInfo{}, ""), + beholderProcessor: nopBeholderProcessor{}, + handler: testConsensusHandler{handle: runVolatileHashableHandle}, } require.NoError(t, s.initLimiters(limits.Factory{Logger: lggr})) return &writeReportHelper{svc: mockSvc, stellar: s} diff --git a/chain_capabilities/stellar/config/config.go b/chain_capabilities/stellar/config/config.go index fd55af917..c44c7cc1c 100644 --- a/chain_capabilities/stellar/config/config.go +++ b/chain_capabilities/stellar/config/config.go @@ -39,6 +39,9 @@ func (c *Config) UnmarshalJSON(bs []byte) error { if err := validateContractStrKey(cfg.CREForwarderAddress); err != nil { return fmt.Errorf("creForwarderAddress: %w", err) } + if cfg.ForwarderLookbackLedgers < 0 { + return fmt.Errorf("forwarderLookbackLedgers must be non-negative") + } *c = Config(cfg) return nil } diff --git a/chain_capabilities/stellar/config/config_test.go b/chain_capabilities/stellar/config/config_test.go index 7921c6eb5..8eb492e49 100644 --- a/chain_capabilities/stellar/config/config_test.go +++ b/chain_capabilities/stellar/config/config_test.go @@ -102,4 +102,18 @@ func TestConfig_UnmarshalJSON(t *testing.T) { require.NoError(t, json.Unmarshal([]byte(input), &cfg)) assert.EqualValues(t, 250, cfg.ForwarderLookbackLedgers) }) + + t.Run("negative forwarderLookbackLedgers", func(t *testing.T) { + t.Parallel() + input := `{ + "chainId":"stellar-testnet", + "network":"stellar", + "creForwarderAddress":"CDLZFC3SYJYDZT7K67VZ75HPJVIEUVNIXF47ZG2FB2RMQQVU2HHGCYSC", + "forwarderLookbackLedgers":-1 + }` + var cfg Config + err := json.Unmarshal([]byte(input), &cfg) + require.Error(t, err) + require.Contains(t, err.Error(), "forwarderLookbackLedgers must be non-negative") + }) }