Skip to content

Commit 95ac6d5

Browse files
authored
Merge pull request #1352 from input-output-hk/feat/web-socket-network-info-provider
LW-10739 Add web socket based network info provider
2 parents 12a0874 + 7036837 commit 95ac6d5

35 files changed

+1522
-28
lines changed

.github/workflows/continuous-integration-e2e.yaml

+3-1
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ env:
1515
HANDLE_PROVIDER_PARAMS: '{"baseUrl":"http://localhost:4011/"}'
1616
STAKE_POOL_CONNECTION_STRING: 'postgresql://postgres:doNoUseThisSecret!@localhost:5435/stake_pool'
1717
STAKE_POOL_TEST_CONNECTION_STRING: 'postgresql://postgres:doNoUseThisSecret!@localhost:5435/stake_pool_test'
18-
NETWORK_INFO_PROVIDER: 'http'
18+
NETWORK_INFO_PROVIDER: 'ws'
1919
NETWORK_INFO_PROVIDER_PARAMS: '{"baseUrl":"http://localhost:4000/"}'
2020
OGMIOS_URL: 'ws://localhost:1340/'
2121
REWARDS_PROVIDER: 'http'
@@ -26,6 +26,7 @@ env:
2626
UTXO_PROVIDER_PARAMS: '{"baseUrl":"http://localhost:4000/"}'
2727
STAKE_POOL_PROVIDER: 'http'
2828
STAKE_POOL_PROVIDER_PARAMS: '{"baseUrl":"http://localhost:4000/"}'
29+
WS_PROVIDER_URL: 'http://localhost:4100/ws'
2930

3031
on:
3132
pull_request:
@@ -78,6 +79,7 @@ jobs:
7879
run: |
7980
yarn workspace @cardano-sdk/e2e test:wallet:epoch0
8081
yarn workspace @cardano-sdk/e2e test:projection
82+
yarn workspace @cardano-sdk/e2e test:ws
8183
8284
- name: Wait for epoch 3
8385
run: |

.github/workflows/k6-web-socket.yaml

+44
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,54 @@ name: K6 WebSocket server load tests
22

33
on:
44
workflow_dispatch:
5+
branches: ['master', 'feat/web-socket-network-info-provider']
6+
inputs:
7+
environment:
8+
description: 'Target environment'
9+
type: choice
10+
required: true
11+
options:
12+
- 'dev'
13+
- 'ops'
14+
- 'staging'
15+
- 'prod'
16+
network:
17+
description: 'Target network'
18+
type: choice
19+
required: true
20+
options:
21+
- 'preview'
22+
- 'preprod'
23+
- 'sanchonet'
24+
- 'mainnet'
25+
wallets:
26+
description: 'Number of wallets to simulate'
27+
type: number
28+
required: true
29+
default: 1000
530

631
jobs:
732
web-socket:
833
runs-on: ubuntu-latest
934
steps:
1035
- name: Checkout
1136
uses: actions/checkout@v3
37+
- name: Run k6 cloud test
38+
uses: grafana/[email protected]
39+
env:
40+
K6_CLOUD_PROJECT_ID: ${{ secrets.K6_CLOUD_PROJECT_ID }}
41+
with:
42+
filename: ./packages/e2e/test/k6/scenarios/web-socket.test.js
43+
cloud: false
44+
token: ${{ secrets.K6_CLOUD_API_TOKEN }}
45+
flags: >
46+
-e TARGET_ENV=${{ inputs.environment }}
47+
-e TARGET_NET=${{ inputs.network }}
48+
-e WALLETS=${{ inputs.wallets }}
49+
--out json=web-socket-results.json
50+
--quiet
51+
- name: Upload performance test results
52+
uses: actions/upload-artifact@v3
53+
with:
54+
name: k6-report
55+
path: web-socket-results.json

Dockerfile

+5
Original file line numberDiff line numberDiff line change
@@ -89,3 +89,8 @@ COPY compose/projector/init.* ./
8989
RUN chmod 755 init.sh
9090
HEALTHCHECK CMD test `curl --fail --silent http://localhost:3000/v1.0.0/health | jq -r ".services[0].projectedTip.blockNo"` -gt 1
9191
CMD ["./init.sh"]
92+
93+
FROM cardano-services as ws-server
94+
WORKDIR /app/packages/cardano-services
95+
HEALTHCHECK CMD curl --fail --silent http://localhost:3000/health
96+
CMD ["bash", "-c", "../../node_modules/.bin/tsx watch --clear-screen=false --conditions=development src/cli start-ws-server"]

compose/common.yml

+23
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,8 @@ x-sdk-environment: &sdk-environment
9999
POSTGRES_USER_FILE_HANDLE: /run/secrets/postgres_user
100100
POSTGRES_USER_FILE_STAKE_POOL: /run/secrets/postgres_user
101101
TOKEN_METADATA_SERVER_URL: https://metadata.world.dev.cardano.org
102+
USE_WEB_SOCKET_API: true
103+
WEB_SOCKET_API_URL: ws://ws-server:3000/ws
102104

103105
services:
104106
cardano-db-sync:
@@ -358,6 +360,27 @@ services:
358360
ports:
359361
- ${HANDLE_API_PORT:-4011}:3000
360362

363+
ws-server:
364+
<<:
365+
- *from-sdk
366+
- *logging
367+
- *provider-server
368+
- *with-postgres
369+
build:
370+
args:
371+
- NETWORK=${NETWORK:-mainnet}
372+
context: ../../
373+
target: ws-server
374+
environment:
375+
<<:
376+
- *sdk-environment
377+
- *provider-server-environment
378+
ports:
379+
- ${WS_SERVER_PORT:-4100}:3000
380+
restart: always
381+
volumes:
382+
- ../..:/app
383+
361384
secrets:
362385
# Replicates the db-sync secret for historical reasons.
363386
# When the SDK was using only one database (the db-sync one) the only secret for database name used was this one

nix/cardano-services/deployments/backend-ingress.nix

+10
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,16 @@
104104
};
105105
}
106106
]
107+
++ lib.optionals values.ws-server.enabled [
108+
{
109+
pathType = "Exact";
110+
path = "/ws";
111+
backend.service = {
112+
name = "${chart.name}-ws-server";
113+
port.name = "http";
114+
};
115+
}
116+
]
107117
++ values.cardano-services.additionalRoutes;
108118
})
109119
values.backend.hostnames;

nix/cardano-services/deployments/default.nix

+14
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,12 @@ in
135135
resources.requests = mkPodResources "150Mi" "200m";
136136
};
137137

138+
ws-server = {
139+
enabled = false;
140+
resources.limits = mkPodResources "300Mi" "300m";
141+
resources.requests = mkPodResources "150Mi" "200m";
142+
};
143+
138144
backend = {
139145
allowedOrigins = lib.concatStringsSep "," allowedOrigins;
140146
passHandleDBArgs = true;
@@ -169,6 +175,7 @@ in
169175
};
170176
imports = [
171177
./options.nix
178+
./ws-server.deployment.nix
172179
./provider.resource.nix
173180
./projector.resource.nix
174181
./backend.provider.nix
@@ -209,6 +216,7 @@ in
209216
};
210217

211218
values = {
219+
ws-server.enabled = true;
212220
stakepool.databaseName = "stakepoolv2";
213221
cardano-services = {
214222
ingresOrder = 99;
@@ -255,6 +263,7 @@ in
255263
};
256264

257265
values = {
266+
ws-server.enabled = true;
258267
blockfrost-worker.enabled = false;
259268
pg-boss-worker.enabled = true;
260269

@@ -322,6 +331,7 @@ in
322331
};
323332

324333
values = {
334+
ws-server.enabled = true;
325335
ingress.enabled = false;
326336
pg-boss-worker.enabled = true;
327337
stakepool.databaseName = "stakepoolv2";
@@ -358,6 +368,7 @@ in
358368
};
359369

360370
values = {
371+
ws-server.enabled = true;
361372
cardano-services = {
362373
ingresOrder = 99;
363374
additionalRoutes = [
@@ -406,6 +417,7 @@ in
406417
};
407418

408419
values = {
420+
ws-server.enabled = true;
409421
stakepool.databaseName = "stakepoolv2";
410422
backend.allowedOrigins = lib.concatStringsSep "," allowedOriginsDev;
411423

@@ -445,6 +457,7 @@ in
445457
};
446458

447459
values = {
460+
ws-server.enabled = true;
448461
stakepool.databaseName = "stakepoolv2";
449462
blockfrost-worker.enabled = true;
450463
pg-boss-worker.enabled = true;
@@ -870,6 +883,7 @@ in
870883
};
871884

872885
values = {
886+
ws-server.enabled = true;
873887
cardano-services = {
874888
ingresOrder = 99;
875889
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
{
2+
lib,
3+
utils,
4+
values,
5+
chart,
6+
config,
7+
...
8+
}: {
9+
templates.ws-server-service = lib.mkIf values.ws-server.enabled {
10+
apiVersion = "v1";
11+
kind = "Service";
12+
metadata = {
13+
name = "${chart.name}-ws-server";
14+
labels = utils.appLabels "ws-server";
15+
};
16+
spec = {
17+
ports = [
18+
{
19+
name = "http";
20+
protocol = "TCP";
21+
port = 3000;
22+
targetPort = 3000;
23+
}
24+
];
25+
selector = utils.appLabels "ws-server";
26+
};
27+
};
28+
29+
templates.ws-server-deployment = lib.mkIf values.ws-server.enabled {
30+
apiVersion = "apps/v1";
31+
kind = "Deployment";
32+
metadata = {
33+
name = "${chart.name}-ws-server";
34+
labels = utils.appLabels "ws-server";
35+
};
36+
spec = {
37+
selector.matchLabels = utils.appLabels "ws-server";
38+
template = {
39+
metadata.labels = utils.appLabels "ws-server";
40+
spec = {
41+
imagePullSecrets = [
42+
{
43+
name = "dockerconfigjson";
44+
}
45+
];
46+
containers = [
47+
{
48+
inherit (values.cardano-services) image;
49+
inherit (values.ws-server) resources;
50+
name = "ws-server";
51+
ports = [
52+
{
53+
containerPort = 3000;
54+
name = "http";
55+
}
56+
];
57+
livenessProbe = {
58+
httpGet = {
59+
path = "/health";
60+
port = 3000;
61+
};
62+
};
63+
securityContext = {
64+
runAsUser = 0;
65+
runAsGroup = 0;
66+
};
67+
args = ["start-ws-server"];
68+
env = utils.mkPodEnv ({
69+
NETWORK = config.network;
70+
DB_CACHE_TTL = "7200";
71+
OGMIOS_URL = "ws://${config.namespace}-cardano-core.${config.namespace}.svc.cluster.local:1337";
72+
73+
POSTGRES_POOL_MAX_DB_SYNC = "2";
74+
POSTGRES_HOST_DB_SYNC = values.postgresName;
75+
POSTGRES_PORT_DB_SYNC = "5432";
76+
POSTGRES_DB_DB_SYNC = "cardano";
77+
POSTGRES_PASSWORD_DB_SYNC = {
78+
valueFrom.secretKeyRef = {
79+
name = "cardano-owner-user.${values.postgresName}.credentials.postgresql.acid.zalan.do";
80+
key = "password";
81+
};
82+
};
83+
POSTGRES_USER_DB_SYNC = {
84+
valueFrom.secretKeyRef = {
85+
name = "cardano-owner-user.${values.postgresName}.credentials.postgresql.acid.zalan.do";
86+
key = "username";
87+
};
88+
};
89+
POSTGRES_SSL_DB_SYNC = "true";
90+
POSTGRES_SSL_CA_FILE_DB_SYNC = "/tls/ca.crt";
91+
});
92+
volumeMounts = [
93+
{
94+
mountPath = "/tls";
95+
name = "tls";
96+
}
97+
];
98+
}
99+
];
100+
volumes = [
101+
{
102+
name = "tls";
103+
secret.secretName = "postgresql-server-cert";
104+
}
105+
];
106+
};
107+
};
108+
};
109+
};
110+
}

packages/cardano-services-client/package.json

+3-1
Original file line numberDiff line numberDiff line change
@@ -57,8 +57,10 @@
5757
"@cardano-sdk/util": "workspace:~",
5858
"axios": "^0.28.0",
5959
"class-validator": "^0.14.0",
60+
"isomorphic-ws": "^5.0.0",
6061
"json-bigint": "~1.0.0",
61-
"ts-log": "^2.2.4"
62+
"ts-log": "^2.2.4",
63+
"ws": "^8.17.1"
6264
},
6365
"files": [
6466
"dist/*",

0 commit comments

Comments
 (0)