Skip to content

Commit 60affe8

Browse files
Unifying grid Client (#851)
* fix: remove unused args in create step functions * change substrate client to grid client usage * sync with grid client changes * fix: setup * test: fix tests * sync with grid client latest changes * update grid-client pkg * update: sync with grid-client updates * update grid client package * mod tidy * refactor: added package grid methods to abstract the access of gridClient * refactor: rest of refactoring, fixed tests * refactor: move substrate client to a separate package and make an interface for it * refactor: move the grid client creation to inside the substrate client and expose grid client * fix: move generate mnemonic back to substrate file * update grid-client package * mod tidy * fix: linting issues * fix: error msg * refactor: change substrate client names to grid client, added grid proxy methods to grid client wrapper * fix: merge error * review comments: renaming new substrate client to grid client * feat: add with network func opt to grid client wrapper, add disable sentry to config * fmt issue * fix: rename substrate to grid * remove unnecessary network parameter * review comments * fix: set disable sentry default to true * fix: added debug, disable sentry as optional args * review comment: fix func opts to not receive booleans
1 parent fc23f07 commit 60affe8

24 files changed

Lines changed: 696 additions & 546 deletions

backend/cmd/cleanup/main.go

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5,16 +5,15 @@ import (
55
cfg "kubecloud/internal/config"
66
"kubecloud/internal/core/models"
77
corepersistence "kubecloud/internal/core/persistence"
8+
"kubecloud/internal/infrastructure/gridclient"
89
"kubecloud/internal/infrastructure/persistence"
9-
"kubecloud/internal/infrastructure/substrate"
1010

1111
"os"
1212

1313
moneycollector "kubecloud/cmd/cleanup/moneycollector"
1414

1515
"github.com/rs/zerolog/log"
1616
"github.com/spf13/viper"
17-
// substrate "github.com/threefoldtech/tfchain/clients/tfchain-client-go"
1817
)
1918

2019
var config cfg.Configuration
@@ -66,17 +65,23 @@ func main() {
6665
}
6766
defer db.Close()
6867

69-
substrateClient, err := substrate.NewTFChainClient(
70-
config.SystemAccount.Network, config.SystemAccount.Mnemonic, "", "",
71-
)
68+
clientOpts := []gridclient.ClientOpts{
69+
gridclient.WithNetwork(config.SystemAccount.Network),
70+
}
71+
if config.Debug {
72+
clientOpts = append(clientOpts, gridclient.WithDebug())
73+
}
74+
if config.DisableSentry {
75+
clientOpts = append(clientOpts, gridclient.WithDisableSentry())
76+
}
7277

78+
gridClient, err := gridclient.NewGridClient(config.SystemAccount.Mnemonic, clientOpts...)
7379
if err != nil {
74-
log.Error().Err(err).Msg("Failed to create TF chain client")
80+
log.Error().Err(err).Msg("Failed to create grid client")
7581
return
7682
}
83+
defer gridClient.Close()
7784

78-
defer substrateClient.Close()
79-
80-
moneyCollector := moneycollector.NewMoneyCollector(corepersistence.NewGormUserRepository(db), config, substrateClient)
85+
moneyCollector := moneycollector.NewMoneyCollector(corepersistence.NewGormUserRepository(db), config, gridClient)
8186
moneyCollector.CollectMoney()
8287
}

backend/cmd/cleanup/moneycollector/money_collector.go

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -3,27 +3,27 @@ package moneycollector
33
import (
44
cfg "kubecloud/internal/config"
55
"kubecloud/internal/core/models"
6-
"kubecloud/internal/infrastructure/substrate"
6+
"kubecloud/internal/infrastructure/gridclient"
77
"sync"
88

99
"github.com/rs/zerolog/log"
1010
)
1111

1212
type MoneyCollector struct {
13-
userRepo models.UserRepository
14-
config cfg.Configuration
15-
substrateClient substrate.Substrate
13+
userRepo models.UserRepository
14+
config cfg.Configuration
15+
gridClient gridclient.GridClient
1616
}
1717

1818
const (
1919
MinBalanceThreshold = 1e5
2020
)
2121

22-
func NewMoneyCollector(userRepo models.UserRepository, config cfg.Configuration, substrateClient substrate.Substrate) *MoneyCollector {
22+
func NewMoneyCollector(userRepo models.UserRepository, config cfg.Configuration, gridClient gridclient.GridClient) *MoneyCollector {
2323
return &MoneyCollector{
24-
userRepo: userRepo,
25-
config: config,
26-
substrateClient: substrateClient,
24+
userRepo: userRepo,
25+
config: config,
26+
gridClient: gridClient,
2727
}
2828
}
2929

@@ -48,14 +48,14 @@ func (m *MoneyCollector) CollectMoney() {
4848
return
4949
}
5050

51-
balance, err := m.substrateClient.GetUserTFTBalance(user.Mnemonic)
51+
freeBalance, err := m.gridClient.GetFreeBalanceTFT(user.Mnemonic)
5252
if err != nil {
5353
log.Error().Err(err).Int("user_id", user.ID).Msg("MoneyCollector: failed to get user balance")
5454
return
5555
}
56-
if balance > MinBalanceThreshold {
57-
log.Debug().Int("user_id", user.ID).Uint64("balance", balance).Msg("MoneyCollector: transferring balance to system account")
58-
if err := m.substrateClient.TransferTFTsToSystem(balance-MinBalanceThreshold, user.Mnemonic); err != nil {
56+
if freeBalance > MinBalanceThreshold {
57+
log.Debug().Int("user_id", user.ID).Uint64("balance", freeBalance).Msg("MoneyCollector: transferring balance to system account")
58+
if err := m.gridClient.TransferTFTsToSystem(freeBalance-MinBalanceThreshold, user.Mnemonic); err != nil {
5959
log.Error().Err(err).Int("user_id", user.ID).Msg("MoneyCollector: failed to transfer balance")
6060
}
6161
return

backend/config-example.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@
4747
"public_key_path": "/home/user/.ssh/id_rsa.pub"
4848
},
4949
"debug": false,
50+
"disable_sentry": true,
5051
"dev_mode": false,
5152
"monitor_balance_interval_in_minutes": 120,
5253
"notify_admins_for_pending_records_in_hours": 24,

backend/internal/api/app/app.go

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -88,13 +88,12 @@ func (app *App) registerEWFWorkflows() {
8888
app.config,
8989
app.core.db,
9090
app.communication.mailService,
91-
app.infra.substrateClient,
91+
app.infra.gridClient,
9292
app.security.kycClient,
9393
app.security.sponsorAddress,
9494
app.security.sponsorKeyPair,
9595
app.core.metrics,
9696
app.communication.notificationDispatcher,
97-
app.infra.gridClient.GridProxyClient,
9897
stripeClient,
9998
)
10099
}

backend/internal/api/app/app_dependencies.go

Lines changed: 18 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import (
1313
"kubecloud/internal/core/services"
1414
"kubecloud/internal/core/workers"
1515
grid "kubecloud/internal/infrastructure/grid"
16+
"kubecloud/internal/infrastructure/gridclient"
1617
"kubecloud/internal/infrastructure/kyc"
1718
"kubecloud/internal/infrastructure/logger"
1819
"kubecloud/internal/infrastructure/mailservice"
@@ -22,7 +23,6 @@ import (
2223
"kubecloud/internal/infrastructure/notification"
2324
"kubecloud/internal/infrastructure/persistence"
2425
"kubecloud/internal/infrastructure/realtime"
25-
"kubecloud/internal/infrastructure/substrate"
2626
"kubecloud/internal/infrastructure/telemetry"
2727

2828
sdktrace "go.opentelemetry.io/otel/sdk/trace"
@@ -87,10 +87,9 @@ type appCommunication struct {
8787

8888
// appInfrastructure contains grid and blockchain related services
8989
type appInfrastructure struct {
90-
gridClient deployer.TFPluginClient
90+
gridClient gridclient.GridClient
9191
firesquidClient graphql.GraphQl
9292
graphql graphql.GraphQl
93-
substrateClient substrate.Substrate
9493
}
9594

9695
func createAppDependencies(ctx context.Context, config cfg.Configuration) (appDependencies, error) {
@@ -269,24 +268,22 @@ func createAppCommunication(config cfg.Configuration, db models.DB, ewfEngine *e
269268
}
270269

271270
func createAppInfrastructure(config cfg.Configuration, tp *sdktrace.TracerProvider) (appInfrastructure, error) {
272-
pluginOpts := []deployer.PluginOpt{
273-
deployer.WithNetwork(config.SystemAccount.Network),
274-
deployer.WithDisableSentry(),
271+
272+
clientOpts := []gridclient.ClientOpts{
273+
gridclient.WithTracerProvider(tp),
274+
gridclient.WithNetwork(config.SystemAccount.Network),
275275
}
276276
if config.Debug {
277-
pluginOpts = append(pluginOpts, deployer.WithLogs())
277+
clientOpts = append(clientOpts, gridclient.WithDebug())
278278
}
279-
280-
if tp != nil {
281-
pluginOpts = append(pluginOpts, deployer.WithTraceProvider(tp))
279+
if config.DisableSentry {
280+
clientOpts = append(clientOpts, gridclient.WithDisableSentry())
282281
}
283282

284-
gridClient, err := deployer.NewTFPluginClient(
285-
config.SystemAccount.Mnemonic,
286-
pluginOpts...,
287-
)
283+
gridClient, err := gridclient.NewGridClient(config.SystemAccount.Mnemonic, clientOpts...)
284+
288285
if err != nil {
289-
return appInfrastructure{}, fmt.Errorf("failed to create TF grid client: %w", err)
286+
return appInfrastructure{}, fmt.Errorf("failed to create grid client: %w", err)
290287
}
291288

292289
fireSquidClient, err := graphql.NewGraphQl(grid.FireSquidURLs[config.SystemAccount.Network]...)
@@ -300,19 +297,10 @@ func createAppInfrastructure(config cfg.Configuration, tp *sdktrace.TracerProvid
300297
return appInfrastructure{}, fmt.Errorf("failed to connect to TF graphql: %w", err)
301298
}
302299

303-
tfChainClient, err := substrate.NewTFChainClient(
304-
config.SystemAccount.Network, config.SystemAccount.Mnemonic,
305-
config.TermsANDConditions.DocumentLink, config.TermsANDConditions.DocumentHash,
306-
)
307-
if err != nil {
308-
return appInfrastructure{}, fmt.Errorf("failed to create tf chain client: %w", err)
309-
}
310-
311300
return appInfrastructure{
312301
gridClient: gridClient,
313302
graphql: graphQl,
314303
firesquidClient: fireSquidClient,
315-
substrateClient: tfChainClient,
316304
}, nil
317305
}
318306

@@ -332,27 +320,24 @@ func (app *App) createHandlers() appHandlers {
332320
// Services
333321
userService := services.NewUserService(
334322
app.core.appCtx, userRepo, voucherRepo, pendingRecordRepo,
335-
app.infra.substrateClient, app.core.ewfEngine,
323+
app.infra.gridClient, app.core.ewfEngine,
336324
app.security.kycClient, app.core.metrics, app.config.MailSender.TimeoutMin,
337325
app.config.Admins,
338326
)
339327

340328
statsService := services.NewStatsService(
341-
userRepo, clusterRepo, app.infra.gridClient.GridProxyClient,
342-
app.infra.substrateClient, app.config.SystemAccount.Mnemonic,
329+
userRepo, clusterRepo, app.infra.gridClient, app.config.SystemAccount.Mnemonic,
343330
)
344331

345332
notificationAPIService := services.NewNotificationService(notificationRepo)
346333

347334
nodeService := services.NewNodeService(
348335
userNodesRepo, userRepo, app.core.appCtx, app.core.ewfEngine,
349-
app.infra.gridClient, app.infra.substrateClient,
336+
app.infra.gridClient,
350337
)
351338

352339
invoiceService := services.NewInvoiceService(
353-
invoiceRepo, userRepo, userNodesRepo,
354-
app.infra.firesquidClient, app.infra.graphql, app.infra.substrateClient,
355-
app.config.Invoice,
340+
invoiceRepo, userRepo, app.config.Invoice,
356341
)
357342

358343
deploymentService := services.NewDeploymentService(
@@ -362,7 +347,7 @@ func (app *App) createHandlers() appHandlers {
362347

363348
adminService := services.NewAdminService(
364349
app.core.appCtx, userRepo, userNodesRepo, pendingRecordRepo, voucherRepo,
365-
transactionRepo, app.infra.substrateClient, app.core.ewfEngine, app.communication.mailService, app.communication.notificationDispatcher, ewfRepo,
350+
transactionRepo, app.infra.gridClient, app.core.ewfEngine, app.communication.mailService, app.communication.notificationDispatcher, ewfRepo,
366351
)
367352

368353
settingsService := services.NewSettingsService(settingsRepo)
@@ -406,7 +391,7 @@ func (app *App) createWorkers() workers.Workers {
406391
app.core.appCtx, userRepo, userNodesRepo, invoiceRepo, clusterRepo, pendingRecordRepo,
407392
app.communication.mailService, app.infra.gridClient, app.core.ewfEngine,
408393
app.communication.notificationDispatcher, app.infra.graphql, app.infra.firesquidClient,
409-
app.infra.substrateClient, app.config.Invoice, app.config.SystemAccount.Mnemonic,
394+
app.config.Invoice, app.config.SystemAccount.Mnemonic,
410395
app.config.Currency, app.config.ClusterHealthCheckIntervalInHours,
411396
app.config.NodeHealthCheck.ReservedNodeHealthCheckIntervalInHours, app.config.NodeHealthCheck.ReservedNodeHealthCheckTimeoutInMinutes, app.config.NodeHealthCheck.ReservedNodeHealthCheckWorkersNum, app.config.MonitorBalanceIntervalInMinutes, app.config.NotifyAdminsForPendingRecordsInHours, app.config.UsersBalanceCheckIntervalInHours, app.config.CheckUserDebtIntervalInHours,
412397
)

backend/internal/api/handlers/setup.go

Lines changed: 30 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@ import (
66
cfg "kubecloud/internal/config"
77
"kubecloud/internal/core/models"
88
corepersistence "kubecloud/internal/core/persistence"
9+
"kubecloud/internal/infrastructure/gridclient"
910
"kubecloud/internal/infrastructure/persistence"
10-
"kubecloud/internal/infrastructure/substrate"
1111

1212
"os"
1313
"os/exec"
@@ -22,13 +22,13 @@ import (
2222
)
2323

2424
type setup struct {
25-
tokenManager auth.TokenManager
26-
substrateClient substrate.Substrate
27-
router *gin.Engine
28-
29-
userRepo models.UserRepository
30-
voucherRepo models.VoucherRepository
31-
invoicesRepo models.InvoiceRepository
25+
tokenManager auth.TokenManager
26+
gridClient gridclient.GridClient
27+
router *gin.Engine
28+
userRepo models.UserRepository
29+
voucherRepo models.VoucherRepository
30+
invoicesRepo models.InvoiceRepository
31+
termsAndConditions cfg.TermsANDConditions
3232
}
3333

3434
func SetUp(t testing.TB) (setup, error) {
@@ -99,6 +99,8 @@ func SetUp(t testing.TB) (setup, error) {
9999
},
100100
"graphql_url": "https://graphql.dev.grid.tf/graphql",
101101
"firesquid_url": "https://firesquid.dev.grid.tf/graphql",
102+
"debug": true,
103+
"disable_sentry": true,
102104
"deployer_workers_num": 3,
103105
"invoice": {
104106
"name": "Name",
@@ -140,10 +142,17 @@ func SetUp(t testing.TB) (setup, error) {
140142
return setup{}, err
141143
}
142144

143-
substrateClient, err := substrate.NewTFChainClient(
144-
configuration.SystemAccount.Network, configuration.SystemAccount.Mnemonic,
145-
configuration.TermsANDConditions.DocumentLink, configuration.TermsANDConditions.DocumentHash,
146-
)
145+
clientOpts := []gridclient.ClientOpts{
146+
gridclient.WithNetwork(configuration.SystemAccount.Network),
147+
}
148+
if configuration.Debug {
149+
clientOpts = append(clientOpts, gridclient.WithDebug())
150+
}
151+
if configuration.DisableSentry {
152+
clientOpts = append(clientOpts, gridclient.WithDisableSentry())
153+
}
154+
155+
gridClient, err := gridclient.NewGridClient(configuration.SystemAccount.Mnemonic, clientOpts...)
147156
if err != nil {
148157
return setup{}, err
149158
}
@@ -173,17 +182,17 @@ func SetUp(t testing.TB) (setup, error) {
173182

174183
// Reset viper to avoid config leakage between tests
175184
viper.Reset()
176-
substrateClient.Close()
185+
gridClient.Close()
177186
})
178187

179188
return setup{
180-
tokenManager: tokenManager,
181-
substrateClient: substrateClient,
182-
router: router,
183-
184-
userRepo: corepersistence.NewGormUserRepository(db),
185-
voucherRepo: corepersistence.NewGormVoucherRepository(db),
186-
invoicesRepo: corepersistence.NewGormInvoiceRepository(db),
189+
tokenManager: tokenManager,
190+
gridClient: gridClient,
191+
router: router,
192+
userRepo: corepersistence.NewGormUserRepository(db),
193+
voucherRepo: corepersistence.NewGormVoucherRepository(db),
194+
invoicesRepo: corepersistence.NewGormInvoiceRepository(db),
195+
termsAndConditions: configuration.TermsANDConditions,
187196
}, nil
188197
}
189198

@@ -200,7 +209,7 @@ func (s setup) CreateTestUser(t *testing.T, email, username string, hashedPasswo
200209
if !mnemonicRequired {
201210
mnemonic = ""
202211
} else {
203-
mnemonic, _, err := s.substrateClient.SetupUserOnTFChain()
212+
mnemonic, _, err := s.gridClient.SetupUserOnTFChain(s.termsAndConditions)
204213
require.NoError(t, err)
205214
sponseeKeyPair, err := auth.KeyPairFromMnemonic(mnemonic)
206215
require.NoError(t, err)

backend/internal/api/handlers/user_handler.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,9 @@ import (
77
"kubecloud/internal/billing"
88
"kubecloud/internal/core/models"
99
"kubecloud/internal/core/services"
10+
"kubecloud/internal/infrastructure/gridclient"
1011
"kubecloud/internal/infrastructure/mailservice"
1112
"kubecloud/internal/infrastructure/notification"
12-
"kubecloud/internal/infrastructure/substrate"
1313
"sort"
1414
"strconv"
1515
"strings"
@@ -739,9 +739,9 @@ func (h *UserHandler) GetUserBalance(c *gin.Context) {
739739
}
740740

741741
OK(c, "Balance is fetched", UserBalanceResponse{
742-
BalanceUSD: substrate.FromUSDMilliCentToUSD(usdMillicentBalance),
743-
DebtUSD: substrate.FromUSDMilliCentToUSD(user.Debt),
744-
PendingBalanceUSD: substrate.FromUSDMilliCentToUSD(pendingAmountInUSDMillicent),
742+
BalanceUSD: gridclient.FromUSDMilliCentToUSD(usdMillicentBalance),
743+
DebtUSD: gridclient.FromUSDMilliCentToUSD(user.Debt),
744+
PendingBalanceUSD: gridclient.FromUSDMilliCentToUSD(pendingAmountInUSDMillicent),
745745
})
746746
}
747747

backend/internal/config/config.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ type Configuration struct {
3030
SSH SSHConfig `json:"ssh" validate:"required,dive"`
3131
Redis RedisConfig `json:"redis" validate:"dive"`
3232
Debug bool `json:"debug"`
33+
DisableSentry bool `json:"disable_sentry" default:"true"`
3334
DevMode bool `json:"dev_mode"` // When true, allows empty SendGridKey and uses FakeMailService
3435
MonitorBalanceIntervalInMinutes int `json:"monitor_balance_interval_in_minutes" validate:"required,gt=0"`
3536
NotifyAdminsForPendingRecordsInHours int `json:"notify_admins_for_pending_records_in_hours" validate:"required,gt=0"`
@@ -155,6 +156,8 @@ var DefaultQueueConfig = ewf.QueueMetadata{
155156
func LoadConfig() (Configuration, error) {
156157
var config Configuration
157158

159+
viper.SetDefault("disable_sentry", true)
160+
158161
// Use mapstructure to ensure JSON tags are respected
159162
decoderConfig := &mapstructure.DecoderConfig{
160163
TagName: "json",

0 commit comments

Comments
 (0)