diff --git a/core/services/functions/connector_handler.go b/core/services/functions/connector_handler.go index a018157a373..8a8710e6ea6 100644 --- a/core/services/functions/connector_handler.go +++ b/core/services/functions/connector_handler.go @@ -78,6 +78,13 @@ func (h *functionsConnectorHandler) HandleGatewayMessage(ctx context.Context, ga } if balance, err := h.subscriptions.GetMaxUserBalance(fromAddr); err != nil || balance.Cmp(h.minimumBalance.ToInt()) < 0 { h.lggr.Errorw("user subscription has insufficient balance", "id", gatewayId, "address", fromAddr, "balance", balance, "minBalance", h.minimumBalance) + response := functions.SecretsResponseBase{ + Success: false, + ErrorMessage: "user subscription has insufficient balance", + } + if err := h.sendResponse(ctx, gatewayId, body, response); err != nil { + h.lggr.Errorw("failed to send response to gateway", "id", gatewayId, "error", err) + } return } diff --git a/core/services/functions/connector_handler_test.go b/core/services/functions/connector_handler_test.go index bb3e2acbabd..7bf98d7501d 100644 --- a/core/services/functions/connector_handler_test.go +++ b/core/services/functions/connector_handler_test.go @@ -39,7 +39,7 @@ func TestFunctionsConnectorHandler(t *testing.T) { allowlist.On("Close", mock.Anything).Return(nil) subscriptions.On("Start", mock.Anything).Return(nil) subscriptions.On("Close", mock.Anything).Return(nil) - handler, err := functions.NewFunctionsConnectorHandler(addr.Hex(), privateKey, storage, allowlist, rateLimiter, subscriptions, *assets.NewLinkFromJuels(0), logger) + handler, err := functions.NewFunctionsConnectorHandler(addr.Hex(), privateKey, storage, allowlist, rateLimiter, subscriptions, *assets.NewLinkFromJuels(100), logger) require.NoError(t, err) handler.SetConnector(connector) @@ -78,7 +78,7 @@ func TestFunctionsConnectorHandler(t *testing.T) { } storage.On("List", ctx, addr).Return(snapshot, nil).Once() allowlist.On("Allow", addr).Return(true).Once() - subscriptions.On("GetMaxUserBalance", mock.Anything).Return(big.NewInt(100), nil) + subscriptions.On("GetMaxUserBalance", mock.Anything).Return(big.NewInt(100), nil).Once() connector.On("SendToGateway", ctx, "gw1", mock.Anything).Run(func(args mock.Arguments) { msg, ok := args[2].(*api.Message) require.True(t, ok) @@ -91,6 +91,7 @@ func TestFunctionsConnectorHandler(t *testing.T) { t.Run("orm error", func(t *testing.T) { storage.On("List", ctx, addr).Return(nil, errors.New("boom")).Once() allowlist.On("Allow", addr).Return(true).Once() + subscriptions.On("GetMaxUserBalance", mock.Anything).Return(big.NewInt(100), nil).Once() connector.On("SendToGateway", ctx, "gw1", mock.Anything).Run(func(args mock.Arguments) { msg, ok := args[2].(*api.Message) require.True(t, ok) @@ -135,7 +136,7 @@ func TestFunctionsConnectorHandler(t *testing.T) { storage.On("Put", ctx, &key, &record, signature).Return(nil).Once() allowlist.On("Allow", addr).Return(true).Once() - subscriptions.On("GetMaxUserBalance", mock.Anything).Return(big.NewInt(100), nil) + subscriptions.On("GetMaxUserBalance", mock.Anything).Return(big.NewInt(100), nil).Once() connector.On("SendToGateway", ctx, "gw1", mock.Anything).Run(func(args mock.Arguments) { msg, ok := args[2].(*api.Message) require.True(t, ok) @@ -148,6 +149,7 @@ func TestFunctionsConnectorHandler(t *testing.T) { t.Run("orm error", func(t *testing.T) { storage.On("Put", ctx, mock.Anything, mock.Anything, mock.Anything).Return(errors.New("boom")).Once() allowlist.On("Allow", addr).Return(true).Once() + subscriptions.On("GetMaxUserBalance", mock.Anything).Return(big.NewInt(100), nil).Once() connector.On("SendToGateway", ctx, "gw1", mock.Anything).Run(func(args mock.Arguments) { msg, ok := args[2].(*api.Message) require.True(t, ok) @@ -163,6 +165,7 @@ func TestFunctionsConnectorHandler(t *testing.T) { require.NoError(t, msg.Sign(privateKey)) storage.On("Put", ctx, mock.Anything, mock.Anything, mock.Anything).Return(s4.ErrWrongSignature).Once() allowlist.On("Allow", addr).Return(true).Once() + subscriptions.On("GetMaxUserBalance", mock.Anything).Return(big.NewInt(100), nil).Once() connector.On("SendToGateway", ctx, "gw1", mock.Anything).Run(func(args mock.Arguments) { msg, ok := args[2].(*api.Message) require.True(t, ok) @@ -177,6 +180,7 @@ func TestFunctionsConnectorHandler(t *testing.T) { msg.Body.Payload = json.RawMessage(`{sdfgdfgoscsicosd:sdf:::sdf ::; xx}`) require.NoError(t, msg.Sign(privateKey)) allowlist.On("Allow", addr).Return(true).Once() + subscriptions.On("GetMaxUserBalance", mock.Anything).Return(big.NewInt(100), nil).Once() connector.On("SendToGateway", ctx, "gw1", mock.Anything).Run(func(args mock.Arguments) { msg, ok := args[2].(*api.Message) require.True(t, ok) @@ -186,6 +190,19 @@ func TestFunctionsConnectorHandler(t *testing.T) { handler.HandleGatewayMessage(ctx, "gw1", &msg) }) + + t.Run("insufficient balance", func(t *testing.T) { + allowlist.On("Allow", addr).Return(true).Once() + subscriptions.On("GetMaxUserBalance", mock.Anything).Return(big.NewInt(0), nil).Once() + connector.On("SendToGateway", ctx, "gw1", mock.Anything).Run(func(args mock.Arguments) { + msg, ok := args[2].(*api.Message) + require.True(t, ok) + require.Equal(t, `{"success":false,"error_message":"user subscription has insufficient balance"}`, string(msg.Body.Payload)) + + }).Return(nil).Once() + + handler.HandleGatewayMessage(ctx, "gw1", &msg) + }) }) t.Run("unsupported method", func(t *testing.T) { @@ -201,6 +218,7 @@ func TestFunctionsConnectorHandler(t *testing.T) { require.NoError(t, msg.Sign(privateKey)) allowlist.On("Allow", addr).Return(true).Once() + subscriptions.On("GetMaxUserBalance", mock.Anything).Return(big.NewInt(100), nil).Once() handler.HandleGatewayMessage(testutils.Context(t), "gw1", &msg) }) })