trac-msb 0.2.9 → 0.2.11

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.
Files changed (143) hide show
  1. package/CODE_OF_CONDUCT.md +128 -0
  2. package/README.md +33 -18
  3. package/docker-compose.yml +1 -0
  4. package/docs/trac_network_http_api.openapi.yaml +889 -0
  5. package/msb.mjs +4 -21
  6. package/package.json +16 -12
  7. package/proto/network/v1/enums/message_type.proto +16 -0
  8. package/proto/network/v1/enums/result_code.proto +84 -0
  9. package/proto/network/v1/messages/broadcast_transaction_request.proto +9 -0
  10. package/proto/network/v1/messages/broadcast_transaction_response.proto +13 -0
  11. package/proto/network/v1/messages/liveness_request.proto +8 -0
  12. package/proto/network/v1/messages/liveness_response.proto +11 -0
  13. package/proto/network/v1/network_message.proto +22 -0
  14. package/rpc/handlers.js +163 -90
  15. package/rpc/routes/v1.js +3 -1
  16. package/rpc/rpc_server.js +3 -3
  17. package/rpc/rpc_services.js +45 -31
  18. package/rpc/utils/helpers.js +82 -51
  19. package/scripts/generate-protobufs.js +37 -12
  20. package/src/config/args.js +46 -0
  21. package/src/config/config.js +99 -5
  22. package/src/config/env.js +86 -7
  23. package/src/core/network/Network.js +79 -46
  24. package/src/core/network/protocols/LegacyProtocol.js +21 -11
  25. package/src/core/network/protocols/NetworkMessages.js +38 -17
  26. package/src/core/network/protocols/ProtocolInterface.js +14 -2
  27. package/src/core/network/protocols/ProtocolSession.js +144 -17
  28. package/src/core/network/protocols/V1Protocol.js +37 -18
  29. package/src/core/network/protocols/connectionPolicies.js +88 -0
  30. package/src/core/network/protocols/legacy/NetworkMessageRouter.js +26 -20
  31. package/src/core/network/protocols/{shared/handlers/base/BaseOperationHandler.js → legacy/handlers/BaseStateOperationHandler.js} +25 -15
  32. package/src/core/network/protocols/legacy/handlers/{GetRequestHandler.js → LegacyGetRequestHandler.js} +6 -6
  33. package/src/core/network/protocols/legacy/handlers/LegacyResponseHandler.js +23 -0
  34. package/src/core/network/protocols/{shared/handlers/RoleOperationHandler.js → legacy/handlers/LegacyRoleOperationHandler.js} +20 -13
  35. package/src/core/network/protocols/{shared/handlers/SubnetworkOperationHandler.js → legacy/handlers/LegacySubnetworkOperationHandler.js} +29 -18
  36. package/src/core/network/protocols/{shared/handlers/TransferOperationHandler.js → legacy/handlers/LegacyTransferOperationHandler.js} +18 -12
  37. package/src/core/network/protocols/legacy/validators/base/BaseResponse.js +1 -1
  38. package/src/core/network/protocols/shared/errors/SharedValidatorRejectionError.js +27 -0
  39. package/src/core/network/protocols/shared/validators/{PartialBootstrapDeployment.js → PartialBootstrapDeploymentValidator.js} +9 -4
  40. package/src/core/network/protocols/shared/validators/{base/PartialOperation.js → PartialOperationValidator.js} +47 -25
  41. package/src/core/network/protocols/shared/validators/{PartialRoleAccess.js → PartialRoleAccessValidator.js} +51 -17
  42. package/src/core/network/protocols/shared/validators/{PartialTransaction.js → PartialTransactionValidator.js} +21 -7
  43. package/src/core/network/protocols/shared/validators/{PartialTransfer.js → PartialTransferValidator.js} +26 -9
  44. package/src/core/network/protocols/v1/NetworkMessageRouter.js +91 -7
  45. package/src/core/network/protocols/v1/V1ProtocolError.js +91 -0
  46. package/src/core/network/protocols/v1/handlers/V1BaseOperationHandler.js +65 -0
  47. package/src/core/network/protocols/v1/handlers/V1BroadcastTransactionOperationHandler.js +389 -0
  48. package/src/core/network/protocols/v1/handlers/V1LivenessOperationHandler.js +87 -0
  49. package/src/core/network/protocols/v1/validators/V1BaseOperation.js +211 -0
  50. package/src/core/network/protocols/v1/validators/V1BroadcastTransactionRequest.js +26 -0
  51. package/src/core/network/protocols/v1/validators/V1BroadcastTransactionResponse.js +276 -0
  52. package/src/core/network/protocols/v1/validators/V1LivenessRequest.js +15 -0
  53. package/src/core/network/protocols/v1/validators/V1LivenessResponse.js +17 -0
  54. package/src/core/network/protocols/v1/validators/V1ValidationSchema.js +210 -0
  55. package/src/core/network/services/ConnectionManager.js +147 -95
  56. package/src/core/network/services/MessageOrchestrator.js +152 -28
  57. package/src/core/network/services/PendingRequestService.js +172 -0
  58. package/src/core/network/services/TransactionCommitService.js +149 -0
  59. package/src/core/network/services/TransactionPoolService.js +133 -22
  60. package/src/core/network/services/TransactionRateLimiterService.js +57 -42
  61. package/src/core/network/services/ValidatorHealthCheckService.js +127 -0
  62. package/src/core/network/services/ValidatorObserverService.js +23 -32
  63. package/src/core/state/State.js +72 -22
  64. package/src/index.js +8 -5
  65. package/src/messages/network/v1/NetworkMessageBuilder.js +61 -81
  66. package/src/messages/network/v1/NetworkMessageDirector.js +16 -50
  67. package/src/messages/state/ApplyStateMessageBuilder.js +1 -1
  68. package/src/utils/Scheduler.js +0 -8
  69. package/src/utils/check.js +1 -1
  70. package/src/utils/constants.js +68 -19
  71. package/src/utils/deepEqualApplyPayload.js +40 -0
  72. package/src/utils/fileUtils.js +13 -0
  73. package/src/utils/helpers.js +10 -1
  74. package/src/utils/logger.js +25 -0
  75. package/src/utils/normalizers.js +38 -0
  76. package/src/utils/protobuf/networkV1.generated.cjs +2460 -0
  77. package/src/utils/protobuf/operationHelpers.js +24 -3
  78. package/src/utils/type.js +26 -0
  79. package/tests/acceptance/v1/account/account.test.mjs +8 -2
  80. package/tests/acceptance/v1/balance/balance.test.mjs +1 -2
  81. package/tests/acceptance/v1/broadcast-transaction/broadcast-transaction.test.mjs +26 -30
  82. package/tests/acceptance/v1/health/health.test.mjs +33 -0
  83. package/tests/acceptance/v1/rpc.test.mjs +3 -2
  84. package/tests/acceptance/v1/tx/tx.test.mjs +50 -17
  85. package/tests/acceptance/v1/tx-details/tx-details.test.mjs +60 -18
  86. package/tests/fixtures/check.fixtures.js +33 -32
  87. package/tests/fixtures/networkV1.fixtures.js +2 -27
  88. package/tests/fixtures/protobuf.fixtures.js +33 -32
  89. package/tests/helpers/StateNetworkFactory.js +2 -2
  90. package/tests/helpers/address.js +6 -0
  91. package/tests/helpers/autobaseTestHelpers.js +2 -1
  92. package/tests/helpers/config.js +2 -1
  93. package/tests/helpers/setupApplyTests.js +6 -10
  94. package/tests/helpers/transactionPayloads.mjs +2 -2
  95. package/tests/unit/messages/network/NetworkMessageBuilder.test.js +241 -81
  96. package/tests/unit/messages/network/NetworkMessageDirector.test.js +225 -81
  97. package/tests/unit/network/LegacyNetworkMessageRouter.test.js +54 -0
  98. package/tests/unit/network/ProtocolSession.test.js +127 -0
  99. package/tests/unit/network/networkModule.test.js +4 -1
  100. package/tests/unit/network/services/ConnectionManager.test.js +450 -0
  101. package/tests/unit/network/services/MessageOrchestrator.test.js +445 -0
  102. package/tests/unit/network/services/PendingRequestService.test.js +431 -0
  103. package/tests/unit/network/services/TransactionCommitService.test.js +246 -0
  104. package/tests/unit/network/services/TransactionPoolService.test.js +489 -0
  105. package/tests/unit/network/services/TransactionRateLimiterService.test.js +139 -0
  106. package/tests/unit/network/services/ValidatorHealthCheckService.test.js +115 -0
  107. package/tests/unit/network/services/services.test.js +17 -0
  108. package/tests/unit/network/utils/v1TestUtils.js +153 -0
  109. package/tests/unit/network/v1/NetworkMessageRouterV1.test.js +151 -0
  110. package/tests/unit/network/v1/V1BaseOperation.test.js +356 -0
  111. package/tests/unit/network/v1/V1BroadcastTransactionOperationHandler.test.js +129 -0
  112. package/tests/unit/network/v1/V1BroadcastTransactionRequest.test.js +53 -0
  113. package/tests/unit/network/v1/V1BroadcastTransactionResponse.test.js +512 -0
  114. package/tests/unit/network/v1/V1LivenessRequest.test.js +32 -0
  115. package/tests/unit/network/v1/V1LivenessResponse.test.js +45 -0
  116. package/tests/unit/network/v1/V1ResultCode.test.js +84 -0
  117. package/tests/unit/network/v1/V1ValidationSchema.test.js +13 -0
  118. package/tests/unit/network/v1/connectionPolicies.test.js +49 -0
  119. package/tests/unit/network/v1/handlers/V1BaseOperationHandler.test.js +284 -0
  120. package/tests/unit/network/v1/handlers/V1BroadcastTransactionOperationHandler.test.js +794 -0
  121. package/tests/unit/network/v1/handlers/V1LivenessOperationHandler.test.js +193 -0
  122. package/tests/unit/network/v1/v1.handlers.test.js +15 -0
  123. package/tests/unit/network/v1/v1.test.js +19 -0
  124. package/tests/unit/network/v1/v1ValidationSchema/broadcastTransactionRequest.test.js +119 -0
  125. package/tests/unit/network/v1/v1ValidationSchema/broadcastTransactionResponse.test.js +136 -0
  126. package/tests/unit/network/v1/v1ValidationSchema/common.test.js +308 -0
  127. package/tests/unit/network/v1/v1ValidationSchema/livenessRequest.test.js +90 -0
  128. package/tests/unit/network/v1/v1ValidationSchema/livenessResponse.test.js +133 -0
  129. package/tests/unit/unit.test.js +2 -2
  130. package/tests/unit/utils/deepEqualApplyPayload/deepEqualApplyPayload.test.js +102 -0
  131. package/tests/unit/utils/fileUtils/readAddressesFromWhitelistFile.test.js +4 -3
  132. package/tests/unit/utils/fileUtils/readBalanceMigrationFile.test.js +3 -2
  133. package/tests/unit/utils/migrationUtils/validateAddressFromIncomingFile.test.js +3 -2
  134. package/tests/unit/utils/protobuf/operationHelpers.test.js +2 -4
  135. package/tests/unit/utils/type/type.test.js +25 -0
  136. package/tests/unit/utils/utils.test.js +2 -0
  137. package/.github/workflows/acceptance-tests.yml +0 -42
  138. package/.github/workflows/publish.yml +0 -33
  139. package/.github/workflows/unit-tests.yml +0 -40
  140. package/proto/network.proto +0 -74
  141. package/src/core/network/protocols/legacy/handlers/ResponseHandler.js +0 -37
  142. package/src/utils/protobuf/network.cjs +0 -840
  143. package/tests/unit/network/ConnectionManager.test.js +0 -191
@@ -4,9 +4,10 @@ import { errorMessageIncludes } from "../../../helpers/regexHelper.js";
4
4
  import { ZERO_LICENSE } from '../../../../src/core/state/utils/nodeEntry.js';
5
5
  import b4a from 'b4a';
6
6
  import { config } from '../../../helpers/config.js';
7
+ import { asAddress } from '../../../helpers/address.js';
7
8
 
8
- const VALID_ADDRESS = 'trac1dguwzsvcsehslh6dgj2mqlsxdn7s5t5vhem56yd0xlg47aq6exzqymhr6u';
9
- const ADMIN_ADDRESS = 'trac1yva2pduhz5yst8jgzmrc9ve0as5mx7tcw6le9srj6xcwqkx9hacqxxhsf9';
9
+ const VALID_ADDRESS = asAddress('6a38e14198866f0fdf4d4495b07e066cfd0a2e8cbe774d11af37d15f741ac984');
10
+ const ADMIN_ADDRESS = asAddress('233aa0b7971509059e4816c782b32fec29b3797876bf92c072d1b0e058c5bf70');
10
11
  const INVALID_ADDRESS = 'notanaddress';
11
12
  const LICENSE_NUMBER_ONE = b4a.alloc(4, 1);
12
13
 
@@ -85,8 +85,8 @@ test('Decode throws on buffer with unknown wire type (skip case)', t => {
85
85
  const bufWithWire7 = b4a.from([0x0F]);
86
86
  try {
87
87
  applyOperations.Operation.decode(bufWithWire7);
88
+ t.fail('Expected decode to throw on unknown wire type');
88
89
  } catch (err) {
89
- console.error('Caught error:', err);
90
90
  t.ok(err instanceof Error && err.message.includes('Could not decode varint'), 'Should throw an error instance to be thrown for unknown wire type');
91
91
  }
92
92
  });
@@ -242,8 +242,6 @@ test('Protobuf encode/decode is order-independent for all operation types', t =>
242
242
 
243
243
  test('encodeV1networkOperation/decodeV1networkOperation roundtrip for network v1 payloads', t => {
244
244
  const payloadsHashMap = new Map([
245
- ['validatorConnectionRequest', networkV1Fixtures.payloadValidatorConnectionRequest],
246
- ['validatorConnectionResponse', networkV1Fixtures.payloadValidatorConnectionResponse],
247
245
  ['livenessRequest', networkV1Fixtures.payloadLivenessRequest],
248
246
  ['livenessResponse', networkV1Fixtures.payloadLivenessResponse],
249
247
  ['broadcastTransactionRequest', networkV1Fixtures.payloadBroadcastTransactionRequest],
@@ -254,7 +252,7 @@ test('encodeV1networkOperation/decodeV1networkOperation roundtrip for network v1
254
252
  const encoded = encodeV1networkOperation(payload);
255
253
  const decoded = decodeV1networkOperation(encoded);
256
254
  t.ok(b4a.isBuffer(encoded) && encoded.length > 0, `Payload ${key} encodes to a non-empty buffer`);
257
- t.ok(JSON.stringify(decoded) === JSON.stringify(payload), `Payload ${key} decodes back correctly`);
255
+ t.alike(decoded, payload, `Payload ${key} decodes back correctly`);
258
256
  }
259
257
  });
260
258
 
@@ -0,0 +1,25 @@
1
+ import test from 'brittle';
2
+ import { isDefined } from '../../../../src/utils/type.js';
3
+
4
+ const assertIsDefined = (t, value, expected, message) => {
5
+ try {
6
+ t.is(isDefined(value), expected, message);
7
+ } catch (err) {
8
+ t.fail(`${message}. Threw: ${err.message}`);
9
+ }
10
+ };
11
+
12
+ test('isDefined returns false for nullish and NaN', t => {
13
+ assertIsDefined(t, null, false, 'null should be treated as not defined');
14
+ assertIsDefined(t, void 0, false, 'undefined should be treated as not defined');
15
+ assertIsDefined(t, NaN, false, 'NaN should be treated as not defined');
16
+ });
17
+
18
+ test('isDefined returns true for defined non-NaN values', t => {
19
+ assertIsDefined(t, 0, true, '0 should be treated as defined');
20
+ assertIsDefined(t, Infinity, true, 'Infinity should be treated as defined');
21
+ assertIsDefined(t, '', true, 'empty string should be treated as defined');
22
+ assertIsDefined(t, false, true, 'boolean false should be treated as defined');
23
+ assertIsDefined(t, {}, true, 'object should be treated as defined');
24
+ assertIsDefined(t, [], true, 'array should be treated as defined');
25
+ });
@@ -6,12 +6,14 @@ async function runTests() {
6
6
  test.pause();
7
7
 
8
8
  await import('./check/check.test.js');
9
+ await import('./deepEqualApplyPayload/deepEqualApplyPayload.test.js');
9
10
  await import('./protobuf/operationHelpers.test.js');
10
11
  await import('./helpers/helpers.test.js');
11
12
  await import('./fileUtils/readAddressesFromWhitelistFile.test.js');
12
13
  await import('./fileUtils/readBalanceMigrationFile.test.js');
13
14
  await import('./migrationUtils/validateAddressFromIncomingFile.test.js');
14
15
  await import('./buffer/buffer.test.js')
16
+ await import('./type/type.test.js');
15
17
  await import('./amountSerialization/amountSerialization.test.js');
16
18
  test.resume();
17
19
  }
@@ -1,42 +0,0 @@
1
- name: MSB-Acceptance-Tests
2
-
3
- on:
4
- workflow_dispatch:
5
- # TODO: re-enable when runners handle acceptance reliably outside local
6
- # workflow_run:
7
- # workflows: ["MSB-Unit-Tests"]
8
- # types:
9
- # - completed
10
-
11
- concurrency:
12
- group: ${{ github.workflow }}-${{ github.ref }}
13
- cancel-in-progress: true
14
-
15
- jobs:
16
- integration-tests:
17
- name: Acceptance Tests
18
- runs-on: ${{ matrix.os }}
19
- # if: ${{ github.event_name == 'workflow_dispatch' || github.event.workflow_run.conclusion == 'success' }}
20
- if: ${{ github.event_name == 'workflow_dispatch' }}
21
- strategy:
22
- matrix:
23
- node-version: [lts/*]
24
- os: [ubuntu-latest, macos-latest, windows-latest]
25
-
26
- steps:
27
- - uses: actions/checkout@v4
28
-
29
- - name: Use Node.js ${{ matrix.node-version }}
30
- uses: actions/setup-node@v3
31
- with:
32
- node-version: ${{ matrix.node-version }}
33
- cache: 'npm'
34
-
35
- - name: Install dependencies
36
- run: npm ci
37
-
38
- - name: Install bare
39
- run: npm i -g bare
40
-
41
- - name: Run Integration Tests
42
- run: npm run test:acceptance
@@ -1,33 +0,0 @@
1
- name: Publish trac-msb to npm on release
2
-
3
- on:
4
- release:
5
- types: [published]
6
-
7
- permissions:
8
- id-token: write # Required for OIDC
9
- contents: read
10
-
11
- jobs:
12
- publish:
13
- runs-on: ubuntu-latest
14
- steps:
15
- - name: Checkout release tag
16
- uses: actions/checkout@v4
17
- with:
18
- ref: ${{ github.event.release.tag_name }}
19
-
20
- - name: Use Node.js
21
- uses: actions/setup-node@v4
22
- with:
23
- node-version: '24'
24
- registry-url: 'https://registry.npmjs.org'
25
- - name: Install dependencies
26
- run: npm ci
27
-
28
- # unit tests are temporarily disabled because they lost stability on GH runners.
29
- #- name: Run unit tests
30
- # run: npm run test:unit:all
31
-
32
- - name: Publish to npm
33
- run: npm publish --access public
@@ -1,40 +0,0 @@
1
- name: MSB-Unit-Tests
2
-
3
- on:
4
- push:
5
- branches:
6
- - main
7
- pull_request:
8
- branches:
9
- - '*'
10
- workflow_dispatch:
11
-
12
- concurrency:
13
- group: ${{ github.workflow }}-${{ github.ref }}
14
- cancel-in-progress: true
15
-
16
- jobs:
17
- tests:
18
- runs-on: ${{ matrix.os }}
19
-
20
- strategy:
21
- matrix:
22
- node-version: [lts/*]
23
- os: [ubuntu-latest, macos-latest, windows-latest]
24
- steps:
25
- - uses: actions/checkout@v4
26
- - name: Use Node.js ${{ matrix.node-version }}
27
- uses: actions/setup-node@v3
28
- with:
29
- node-version: ${{ matrix.node-version }}
30
- cache: 'npm'
31
- - name: Install dependencies
32
- run: npm ci
33
- - name: Install bare
34
- run: npm i -g bare
35
- - name: Run all tests
36
- run: npm run test:unit:all
37
- # For now acceptance tests should be disable due to instability of the running MSB instance in the github actions environment
38
- # Github machines are not powerful enough to run MSB, and we won't ever finish our tests.
39
- # - name: Run rpc acceptance tests
40
- # run: npm run test:acceptance
@@ -1,74 +0,0 @@
1
- syntax = "proto3";
2
-
3
- package network.v1;
4
-
5
- enum MessageType {
6
- MESSAGE_TYPE_UNSPECIFIED = 0;
7
- MESSAGE_TYPE_VALIDATOR_CONNECTION_REQUEST = 1;
8
- MESSAGE_TYPE_VALIDATOR_CONNECTION_RESPONSE = 2;
9
- MESSAGE_TYPE_LIVENESS_REQUEST = 3;
10
- MESSAGE_TYPE_LIVENESS_RESPONSE = 4;
11
- MESSAGE_TYPE_BROADCAST_TRANSACTION_REQUEST = 5;
12
- MESSAGE_TYPE_BROADCAST_TRANSACTION_RESPONSE = 6;
13
- }
14
-
15
- enum ResultCode {
16
- RESULT_CODE_UNSPECIFIED = 0;
17
- RESULT_CODE_OK = 1;
18
- RESULT_CODE_INVALID_PAYLOAD = 2;
19
- RESULT_CODE_UNSUPPORTED_VERSION = 3;
20
- RESULT_CODE_RATE_LIMITED = 4;
21
- RESULT_CODE_TIMEOUT = 5;
22
- RESULT_CODE_SIGNATURE_INVALID = 6;
23
- }
24
-
25
- message ValidatorConnectionRequest {
26
- string issuer_address = 1;
27
- bytes nonce = 2;
28
- bytes signature = 3;
29
- }
30
-
31
- message ValidatorConnectionResponse {
32
- string issuer_address = 1;
33
- bytes nonce = 2;
34
- bytes signature = 3;
35
- ResultCode result = 4;
36
- }
37
-
38
- message LivenessRequest {
39
- bytes nonce = 1;
40
- bytes signature = 2;
41
- }
42
-
43
- message LivenessResponse {
44
- bytes nonce = 1;
45
- bytes signature = 2;
46
- ResultCode result = 3;
47
- }
48
-
49
- message BroadcastTransactionRequest {
50
- bytes data = 1; // binary encoded payload
51
- bytes nonce = 2;
52
- bytes signature = 3;
53
- }
54
-
55
- message BroadcastTransactionResponse {
56
- bytes nonce = 1;
57
- bytes signature = 2;
58
- ResultCode result = 3;
59
- }
60
-
61
- message MessageHeader {
62
- MessageType type = 1;
63
- string id = 2;
64
- uint64 timestamp = 3;
65
- oneof field {
66
- ValidatorConnectionRequest validator_connection_request = 4;
67
- ValidatorConnectionResponse validator_connection_response = 5;
68
- LivenessRequest liveness_request = 6;
69
- LivenessResponse liveness_response = 7;
70
- BroadcastTransactionRequest broadcast_transaction_request = 8;
71
- BroadcastTransactionResponse broadcast_transaction_response = 9;
72
- }
73
- repeated string capabilities = 10;
74
- }
@@ -1,37 +0,0 @@
1
- import ValidatorResponse from '../validators/ValidatorResponse.js';
2
- import PeerWallet from 'trac-wallet';
3
-
4
- class ResponseHandler {
5
- #responseValidator;
6
- #connectionManager;
7
-
8
-
9
- constructor(state, wallet, connectionManager ,config) {
10
- this.#responseValidator = new ValidatorResponse(state, wallet, config);
11
- this.#connectionManager = connectionManager;
12
-
13
- }
14
-
15
- async handle(message, connection, channelString) {
16
- await this.#handleValidatorResponse(message, connection, channelString);
17
- }
18
-
19
- async #handleValidatorResponse(message, connection, channelString) {
20
- const isValid = await this.#responseValidator.validate(message, channelString);
21
- if (isValid) {
22
- const validatorAddressString = message.address;
23
- const validatorPublicKey = PeerWallet.decodeBech32m(validatorAddressString);
24
-
25
- if (this.#connectionManager.connected(validatorPublicKey)) {
26
- return;
27
- // TODO: What we should return? Or maybe we should throw?
28
- }
29
-
30
- this.#connectionManager.addValidator(validatorPublicKey, connection)
31
- } else {
32
- throw new Error("Validator response verification failed");
33
- }
34
- }
35
- }
36
-
37
- export default ResponseHandler;