@cardano-sdk/e2e 0.43.0 → 0.44.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.env.example +2 -2
- package/CHANGELOG.md +18 -0
- package/dist/cjs/factories.d.ts.map +1 -1
- package/dist/cjs/factories.js +14 -8
- package/dist/cjs/factories.js.map +1 -1
- package/dist/cjs/tsconfig.tsbuildinfo +1 -1
- package/dist/esm/factories.d.ts.map +1 -1
- package/dist/esm/factories.js +14 -8
- package/dist/esm/factories.js.map +1 -1
- package/dist/esm/tsconfig.tsbuildinfo +1 -1
- package/package.json +19 -19
- package/src/factories.ts +36 -10
- package/test/k6/scenarios/wallets.test.js +1 -1
- package/test/k6/scenarios/web-socket.test.js +84 -20
- package/test/long-running/webSocket.test.ts +4 -2
- package/test/wallet_epoch_3/PersonalWallet/conwayTransactions.test.ts +6 -6
- package/test/ws-server/webSocket.test.ts +197 -28
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cardano-sdk/e2e",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.44.0",
|
|
4
4
|
"description": "End to end tests for the cardano-js-sdk packages.",
|
|
5
5
|
"repository": "https://github.com/input-output-hk/cardano-js-sdk",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -30,7 +30,7 @@
|
|
|
30
30
|
"test:ogmios": "jest -c jest.config.js --forceExit --selectProjects ogmios --runInBand --verbose",
|
|
31
31
|
"test:pg-boss": "jest -c jest.config.js --forceExit --selectProjects pg-boss --runInBand --verbose",
|
|
32
32
|
"test:providers": "jest -c jest.config.js --forceExit --selectProjects providers --runInBand --verbose",
|
|
33
|
-
"test:wallet": "yarn wait-for-network-init ; yarn test:wallet:epoch0 &&
|
|
33
|
+
"test:wallet": "yarn wait-for-network-init ; yarn test:wallet:epoch0 && { yarn wait-for-network-epoch-3 ; yarn test:wallet:epoch3 && yarn test:ws ; }",
|
|
34
34
|
"test:wallet:epoch0": "jest -c jest.config.js --forceExit --selectProjects wallet_epoch_0 --runInBand --verbose",
|
|
35
35
|
"test:wallet:epoch3": "jest -c jest.config.js --forceExit --selectProjects wallet_epoch_3 --runInBand --verbose",
|
|
36
36
|
"test:wallet-real-ada": "NETWORK_SPEED=slow jest -c jest.config.js --forceExit --selectProjects wallet-real-ada --runInBand --verbose",
|
|
@@ -76,20 +76,20 @@
|
|
|
76
76
|
"dependencies": {
|
|
77
77
|
"@cardano-foundation/ledgerjs-hw-app-cardano": "^7.1.2",
|
|
78
78
|
"@cardano-ogmios/client": "6.5.0",
|
|
79
|
-
"@cardano-sdk/cardano-services": "~0.
|
|
80
|
-
"@cardano-sdk/cardano-services-client": "~0.
|
|
81
|
-
"@cardano-sdk/core": "~0.
|
|
79
|
+
"@cardano-sdk/cardano-services": "~0.31.0",
|
|
80
|
+
"@cardano-sdk/cardano-services-client": "~0.21.0",
|
|
81
|
+
"@cardano-sdk/core": "~0.41.0",
|
|
82
82
|
"@cardano-sdk/crypto": "~0.1.30",
|
|
83
|
-
"@cardano-sdk/hardware-ledger": "~0.12.
|
|
84
|
-
"@cardano-sdk/hardware-trezor": "~0.6.
|
|
85
|
-
"@cardano-sdk/input-selection": "~0.13.
|
|
86
|
-
"@cardano-sdk/key-management": "~0.24.
|
|
87
|
-
"@cardano-sdk/ogmios": "~0.18.
|
|
88
|
-
"@cardano-sdk/tx-construction": "~0.21.
|
|
83
|
+
"@cardano-sdk/hardware-ledger": "~0.12.6",
|
|
84
|
+
"@cardano-sdk/hardware-trezor": "~0.6.6",
|
|
85
|
+
"@cardano-sdk/input-selection": "~0.13.22",
|
|
86
|
+
"@cardano-sdk/key-management": "~0.24.5",
|
|
87
|
+
"@cardano-sdk/ogmios": "~0.18.2",
|
|
88
|
+
"@cardano-sdk/tx-construction": "~0.21.7",
|
|
89
89
|
"@cardano-sdk/util": "~0.15.5",
|
|
90
|
-
"@cardano-sdk/util-dev": "~0.23.
|
|
91
|
-
"@cardano-sdk/util-rxjs": "~0.7.
|
|
92
|
-
"@cardano-sdk/wallet": "~0.44.
|
|
90
|
+
"@cardano-sdk/util-dev": "~0.23.2",
|
|
91
|
+
"@cardano-sdk/util-rxjs": "~0.7.35",
|
|
92
|
+
"@cardano-sdk/wallet": "~0.44.6",
|
|
93
93
|
"@dcspark/cardano-multiplatform-lib-nodejs": "^3.1.1",
|
|
94
94
|
"@shiroyasha9/axios-fetch-adapter": "1.0.3",
|
|
95
95
|
"axios": "^1.7.4",
|
|
@@ -119,10 +119,10 @@
|
|
|
119
119
|
"@babel/core": "^7.18.2",
|
|
120
120
|
"@babel/preset-env": "^7.18.2",
|
|
121
121
|
"@babel/preset-typescript": "^7.17.12",
|
|
122
|
-
"@cardano-sdk/dapp-connector": "~0.12.
|
|
123
|
-
"@cardano-sdk/projection": "~0.12.
|
|
124
|
-
"@cardano-sdk/projection-typeorm": "~0.9.
|
|
125
|
-
"@cardano-sdk/web-extension": "~0.34.
|
|
122
|
+
"@cardano-sdk/dapp-connector": "~0.12.39",
|
|
123
|
+
"@cardano-sdk/projection": "~0.12.2",
|
|
124
|
+
"@cardano-sdk/projection-typeorm": "~0.9.2",
|
|
125
|
+
"@cardano-sdk/web-extension": "~0.34.5",
|
|
126
126
|
"@dcspark/cardano-multiplatform-lib-browser": "^3.1.1",
|
|
127
127
|
"@emurgo/cardano-message-signing-asmjs": "^1.0.1",
|
|
128
128
|
"@types/bunyan": "^1.8.8",
|
|
@@ -182,5 +182,5 @@
|
|
|
182
182
|
"publishConfig": {
|
|
183
183
|
"access": "public"
|
|
184
184
|
},
|
|
185
|
-
"gitHead": "
|
|
185
|
+
"gitHead": "7b57a20fa480214f31a2773e7da732f2572243ce"
|
|
186
186
|
}
|
package/src/factories.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
2
|
+
// cSpell:ignore dcspark ledgerjs multiplatform shiroyasha vespaiach
|
|
2
3
|
import * as CML from '@dcspark/cardano-multiplatform-lib-nodejs';
|
|
3
4
|
import * as Crypto from '@cardano-sdk/crypto';
|
|
4
5
|
import {
|
|
@@ -64,9 +65,10 @@ const customHttpFetchAdapter = isNodeJs ? undefined : require('@shiroyasha9/axio
|
|
|
64
65
|
const HTTP_PROVIDER = 'http';
|
|
65
66
|
const OGMIOS_PROVIDER = 'ogmios';
|
|
66
67
|
const STUB_PROVIDER = 'stub';
|
|
67
|
-
const MISSING_URL_PARAM = 'Missing URL';
|
|
68
68
|
const WS_PROVIDER = 'ws';
|
|
69
69
|
|
|
70
|
+
const MISSING_URL_PARAM = 'Missing URL';
|
|
71
|
+
|
|
70
72
|
export type CreateKeyAgent = (dependencies: KeyAgentDependencies) => Promise<AsyncKeyAgent>;
|
|
71
73
|
export const keyManagementFactory = new ProviderFactory<CreateKeyAgent>();
|
|
72
74
|
export const assetProviderFactory = new ProviderFactory<AssetProvider>();
|
|
@@ -93,6 +95,25 @@ addressDiscoveryFactory.register(
|
|
|
93
95
|
bip32Ed25519Factory.register('CML', async () => new Crypto.CmlBip32Ed25519(CML));
|
|
94
96
|
bip32Ed25519Factory.register('Sodium', async () => new Crypto.SodiumBip32Ed25519());
|
|
95
97
|
|
|
98
|
+
// Web Socket
|
|
99
|
+
|
|
100
|
+
let wsClient: CardanoWsClient;
|
|
101
|
+
|
|
102
|
+
const getWsClient = async (logger: Logger) => {
|
|
103
|
+
if (wsClient) return wsClient;
|
|
104
|
+
|
|
105
|
+
const env = getEnv(walletVariables);
|
|
106
|
+
const chainHistoryProvider = await chainHistoryProviderFactory.create(
|
|
107
|
+
HTTP_PROVIDER,
|
|
108
|
+
env.TEST_CLIENT_CHAIN_HISTORY_PROVIDER_PARAMS,
|
|
109
|
+
logger
|
|
110
|
+
);
|
|
111
|
+
|
|
112
|
+
if (env.WS_PROVIDER_URL === undefined) throw new Error(`${networkInfoHttpProvider.name}: ${MISSING_URL_PARAM}`);
|
|
113
|
+
|
|
114
|
+
return (wsClient = new CardanoWsClient({ chainHistoryProvider, logger }, { url: new URL(env.WS_PROVIDER_URL) }));
|
|
115
|
+
};
|
|
116
|
+
|
|
96
117
|
// Asset providers
|
|
97
118
|
|
|
98
119
|
assetProviderFactory.register(HTTP_PROVIDER, async (params: any, logger: Logger): Promise<AssetProvider> => {
|
|
@@ -120,6 +141,11 @@ chainHistoryProviderFactory.register(
|
|
|
120
141
|
}
|
|
121
142
|
);
|
|
122
143
|
|
|
144
|
+
chainHistoryProviderFactory.register(
|
|
145
|
+
WS_PROVIDER,
|
|
146
|
+
async (_params: any, logger: Logger) => (await getWsClient(logger)).chainHistoryProvider
|
|
147
|
+
);
|
|
148
|
+
|
|
123
149
|
networkInfoProviderFactory.register(
|
|
124
150
|
HTTP_PROVIDER,
|
|
125
151
|
async (params: any, logger: Logger): Promise<NetworkInfoProvider> => {
|
|
@@ -131,15 +157,10 @@ networkInfoProviderFactory.register(
|
|
|
131
157
|
}
|
|
132
158
|
);
|
|
133
159
|
|
|
134
|
-
networkInfoProviderFactory.register(
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
const wsClient = new CardanoWsClient({ logger }, { url: new URL(env.WS_PROVIDER_URL) });
|
|
140
|
-
|
|
141
|
-
return Promise.resolve(wsClient.networkInfoProvider);
|
|
142
|
-
});
|
|
160
|
+
networkInfoProviderFactory.register(
|
|
161
|
+
WS_PROVIDER,
|
|
162
|
+
async (_params: any, logger: Logger) => (await getWsClient(logger)).networkInfoProvider
|
|
163
|
+
);
|
|
143
164
|
|
|
144
165
|
rewardsProviderFactory.register(HTTP_PROVIDER, async (params: any, logger: Logger): Promise<RewardsProvider> => {
|
|
145
166
|
if (params.baseUrl === undefined) throw new Error(`${rewardsHttpProvider.name}: ${MISSING_URL_PARAM}`);
|
|
@@ -191,6 +212,11 @@ utxoProviderFactory.register(HTTP_PROVIDER, async (params: any, logger: Logger):
|
|
|
191
212
|
});
|
|
192
213
|
});
|
|
193
214
|
|
|
215
|
+
utxoProviderFactory.register(
|
|
216
|
+
WS_PROVIDER,
|
|
217
|
+
async (_params: any, logger: Logger) => (await getWsClient(logger)).utxoProvider
|
|
218
|
+
);
|
|
219
|
+
|
|
194
220
|
handleProviderFactory.register(HTTP_PROVIDER, async (params: any, logger: Logger): Promise<HandleProvider> => {
|
|
195
221
|
if (params.baseUrl === undefined) throw new Error(`${handleHttpProvider.name}: ${MISSING_URL_PARAM}`);
|
|
196
222
|
|
|
@@ -245,7 +245,7 @@ const syncWallet = ({ wallet, poolAddress }) => {
|
|
|
245
245
|
if (RUN_MODE === RunMode.Restore) {
|
|
246
246
|
sdkCom.stakePoolSearch(poolAddress);
|
|
247
247
|
}
|
|
248
|
-
sdkCom.
|
|
248
|
+
sdkCom.stakePoolStats();
|
|
249
249
|
|
|
250
250
|
// Consider the wallet synced by tracking its first address
|
|
251
251
|
syncedWallets.add(addresses[0]);
|
|
@@ -1,15 +1,25 @@
|
|
|
1
|
+
// cSpell:ignore loadimpact
|
|
2
|
+
|
|
1
3
|
import * as k6Utils from '../../../../util-dev/dist/cjs/k6-utils.js';
|
|
2
4
|
import { Counter, Trend } from 'k6/metrics';
|
|
5
|
+
import { SharedArray } from 'k6/data';
|
|
3
6
|
import { check } from 'k6';
|
|
4
7
|
import ws from 'k6/ws';
|
|
5
8
|
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
// eslint-disable-next-line no-undef
|
|
9
|
-
|
|
9
|
+
const { HD_ACTIVE_ADDR_COUNT, HD_MAX_TX_HISTORY, TARGET_NET, WALLETS } = Object.assign(
|
|
10
|
+
{ HD_ACTIVE_ADDR_COUNT: '10', HD_MAX_TX_HISTORY: '100', TARGET_NET: 'mainnet', WALLETS: '100' },
|
|
11
|
+
// eslint-disable-next-line no-undef
|
|
12
|
+
__ENV
|
|
13
|
+
);
|
|
10
14
|
|
|
15
|
+
// eslint-disable-next-line no-undef
|
|
16
|
+
const dut = k6Utils.getDut(__ENV, { networks: ['mainnet', 'preprod'] });
|
|
11
17
|
const url = `wss://${dut}/ws`;
|
|
12
18
|
|
|
19
|
+
const activeAddrCount = Number.parseInt(HD_ACTIVE_ADDR_COUNT, 10);
|
|
20
|
+
const maxTxHistory = Number.parseInt(HD_MAX_TX_HISTORY, 10);
|
|
21
|
+
const numWallets = Number.parseInt(WALLETS, 10);
|
|
22
|
+
|
|
13
23
|
export const options = {
|
|
14
24
|
ext: {
|
|
15
25
|
loadimpact: {
|
|
@@ -21,28 +31,84 @@ export const options = {
|
|
|
21
31
|
connections: {
|
|
22
32
|
executor: 'ramping-vus',
|
|
23
33
|
gracefulRampDown: '0s',
|
|
24
|
-
gracefulStop: '
|
|
25
|
-
stages: [{ duration: '3s', target:
|
|
26
|
-
startVUs:
|
|
34
|
+
gracefulStop: '10m',
|
|
35
|
+
stages: [{ duration: '3s', target: numWallets }],
|
|
36
|
+
startVUs: 1
|
|
27
37
|
}
|
|
28
38
|
}
|
|
29
39
|
};
|
|
30
40
|
|
|
41
|
+
/** Wallet addresses extracted from the JSON dump file */
|
|
42
|
+
const fileName = `../../dump/addresses/${TARGET_NET}.json`;
|
|
43
|
+
// eslint-disable-next-line no-undef
|
|
44
|
+
const walletsOrig = new SharedArray('walletsData', () => JSON.parse(open(fileName)));
|
|
45
|
+
|
|
46
|
+
export const setup = () => {
|
|
47
|
+
check(
|
|
48
|
+
undefined,
|
|
49
|
+
Object.fromEntries(
|
|
50
|
+
[`Number of wallets: ${numWallets}`, `Max transactions per wallet: ${maxTxHistory}`].map((_) => [_, () => true])
|
|
51
|
+
)
|
|
52
|
+
);
|
|
53
|
+
|
|
54
|
+
// Remove "big transaction history wallets"
|
|
55
|
+
const filteredWallets = walletsOrig.filter(({ tx_count }) => tx_count < maxTxHistory);
|
|
56
|
+
// Create chunks of `activeAddrCount` addresses per HD wallet
|
|
57
|
+
const wallets = k6Utils.chunkArray(filteredWallets, activeAddrCount);
|
|
58
|
+
|
|
59
|
+
return { wallets: wallets.slice(0, numWallets) };
|
|
60
|
+
};
|
|
61
|
+
|
|
31
62
|
const operationalTrend = new Trend('_operational', true);
|
|
63
|
+
const syncTrend = new Trend('_sync', true);
|
|
64
|
+
const syncCount = new Counter('_sync_count');
|
|
65
|
+
const transactionsTrend = new Trend('_transactions_per_wallet');
|
|
32
66
|
const unexpectedCloseCounter = new Counter('_unexpected_close');
|
|
33
67
|
|
|
34
|
-
|
|
68
|
+
const getDummyAddr = (addr, idx, suffix = 'mh') => {
|
|
69
|
+
const last3Chars = addr.slice(-3);
|
|
70
|
+
const updateChars = last3Chars !== `${suffix}${idx}` ? `${suffix}${idx}` : `${idx}${suffix}`;
|
|
71
|
+
return addr.slice(0, -3) + updateChars;
|
|
72
|
+
};
|
|
73
|
+
|
|
74
|
+
export const run = ({ wallets }) => {
|
|
35
75
|
const begin = Date.now();
|
|
76
|
+
// eslint-disable-next-line no-undef
|
|
77
|
+
const vu = __VU;
|
|
78
|
+
const wallet = wallets[vu % wallets.length]; // each wallet is a collection of addresses
|
|
36
79
|
|
|
37
80
|
const res = ws.connect(url, null, (socket) => {
|
|
38
81
|
let closed = false;
|
|
39
|
-
let
|
|
82
|
+
let requestId = 0;
|
|
83
|
+
let transactionsCount = 0;
|
|
40
84
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
85
|
+
const nextAddress = () => {
|
|
86
|
+
// Simplified address discovery with 50 fake addresses
|
|
87
|
+
if (++requestId > wallet.length + 50) {
|
|
88
|
+
transactionsTrend.add(transactionsCount);
|
|
89
|
+
syncTrend.add(Date.now() - begin);
|
|
90
|
+
syncCount.add(1);
|
|
91
|
+
|
|
92
|
+
return socket.setTimeout(() => {
|
|
93
|
+
closed = true;
|
|
94
|
+
socket.close();
|
|
95
|
+
}, 1000);
|
|
45
96
|
}
|
|
97
|
+
|
|
98
|
+
const address =
|
|
99
|
+
requestId <= wallet.length
|
|
100
|
+
? wallet[requestId - 1].address
|
|
101
|
+
: getDummyAddr(wallet[0].address, requestId - wallet.length);
|
|
102
|
+
|
|
103
|
+
socket.send(JSON.stringify({ requestId, txsByAddresses: { addresses: [address], lower: 0 } }));
|
|
104
|
+
};
|
|
105
|
+
|
|
106
|
+
socket.on('message', (message) => {
|
|
107
|
+
const { clientId, responseTo, transactions } = JSON.parse(message);
|
|
108
|
+
|
|
109
|
+
if (clientId) operationalTrend.add(Date.now() - begin);
|
|
110
|
+
if (clientId || responseTo) nextAddress();
|
|
111
|
+
if (transactions) transactionsCount += transactions.length;
|
|
46
112
|
});
|
|
47
113
|
|
|
48
114
|
// Count unexpected close
|
|
@@ -51,13 +117,11 @@ export const run = () => {
|
|
|
51
117
|
});
|
|
52
118
|
|
|
53
119
|
// Heartbeat
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
socket.close();
|
|
60
|
-
}, 80 * 1000);
|
|
120
|
+
const heartbeat = () => {
|
|
121
|
+
socket.send('{}');
|
|
122
|
+
socket.setTimeout(heartbeat, 30 * 1000);
|
|
123
|
+
};
|
|
124
|
+
heartbeat();
|
|
61
125
|
});
|
|
62
126
|
|
|
63
127
|
check(res, { 'status is 101': (r) => r && r.status === 101 });
|
|
@@ -1,13 +1,15 @@
|
|
|
1
|
-
import { CardanoWsClient } from '@cardano-sdk/cardano-services-client';
|
|
1
|
+
import { CardanoWsClient, chainHistoryHttpProvider } from '@cardano-sdk/cardano-services-client';
|
|
2
2
|
import { getEnv, walletVariables } from '../../src';
|
|
3
3
|
import { logger } from '@cardano-sdk/util-dev';
|
|
4
4
|
|
|
5
5
|
const env = getEnv([...walletVariables]);
|
|
6
6
|
|
|
7
7
|
describe('Web Socket', () => {
|
|
8
|
+
const chainHistoryProvider = chainHistoryHttpProvider({ logger, ...env.TEST_CLIENT_CHAIN_HISTORY_PROVIDER_PARAMS });
|
|
8
9
|
let client: CardanoWsClient;
|
|
9
10
|
|
|
10
|
-
const openClient = () =>
|
|
11
|
+
const openClient = () =>
|
|
12
|
+
(client = new CardanoWsClient({ chainHistoryProvider, logger }, { url: new URL(env.WS_PROVIDER_URL) }));
|
|
11
13
|
|
|
12
14
|
const closeClient = () => (client ? client.close() : Promise.resolve());
|
|
13
15
|
|
|
@@ -451,8 +451,8 @@ describe('PersonalWallet/conwayTransactions', () => {
|
|
|
451
451
|
});
|
|
452
452
|
|
|
453
453
|
describe('with proposal procedure', () => {
|
|
454
|
-
let actionId: Cardano.GovernanceActionId;
|
|
455
454
|
let confirmedTx: Cardano.HydratedTx;
|
|
455
|
+
let id: Cardano.TransactionId;
|
|
456
456
|
let proposalProcedures: Cardano.ProposalProcedure[];
|
|
457
457
|
|
|
458
458
|
beforeAll(async () => {
|
|
@@ -519,10 +519,7 @@ describe('PersonalWallet/conwayTransactions', () => {
|
|
|
519
519
|
.customize(({ txBody }) => ({ ...txBody, proposalProcedures }))
|
|
520
520
|
.build()
|
|
521
521
|
.sign();
|
|
522
|
-
|
|
523
|
-
confirmedTx = tx;
|
|
524
|
-
|
|
525
|
-
actionId = { actionIndex: 0, id };
|
|
522
|
+
[id, confirmedTx] = await submitAndConfirm(wallet, signedTx.tx, 1);
|
|
526
523
|
});
|
|
527
524
|
|
|
528
525
|
it('parameter_change_action correctly submits protocol parameters update', () => {
|
|
@@ -533,7 +530,10 @@ describe('PersonalWallet/conwayTransactions', () => {
|
|
|
533
530
|
const votingProcedures: Cardano.VotingProcedures = [
|
|
534
531
|
{
|
|
535
532
|
voter: { __typename: VoterType.dRepKeyHash, credential: dRepCredential },
|
|
536
|
-
votes: [
|
|
533
|
+
votes: [
|
|
534
|
+
{ actionId: { actionIndex: 0, id }, votingProcedure: { anchor, vote: Vote.abstain } },
|
|
535
|
+
{ actionId: { actionIndex: 1, id }, votingProcedure: { anchor: null, vote: Vote.yes } }
|
|
536
|
+
]
|
|
537
537
|
}
|
|
538
538
|
];
|
|
539
539
|
const signedTx = await dRepWallet
|