trac-msb 0.2.8 → 0.2.10

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 (151) hide show
  1. package/.github/workflows/acceptance-tests.yml +7 -11
  2. package/.github/workflows/lint-pr-title.yml +26 -0
  3. package/.github/workflows/unit-tests.yml +2 -8
  4. package/CODE_OF_CONDUCT.md +128 -0
  5. package/README.md +33 -18
  6. package/docker-compose.yml +1 -0
  7. package/docs/trac_network_http_api.openapi.yaml +889 -0
  8. package/msb.mjs +5 -22
  9. package/package.json +14 -10
  10. package/proto/network.proto +74 -0
  11. package/rpc/create_server.js +2 -2
  12. package/rpc/handlers.js +165 -92
  13. package/rpc/routes/v1.js +3 -1
  14. package/rpc/rpc_server.js +4 -4
  15. package/rpc/rpc_services.js +62 -25
  16. package/rpc/utils/helpers.js +83 -52
  17. package/src/config/args.js +46 -0
  18. package/src/config/config.js +78 -5
  19. package/src/config/env.js +70 -3
  20. package/src/core/network/Network.js +34 -70
  21. package/src/core/network/identity/NetworkWalletFactory.js +2 -2
  22. package/src/core/network/protocols/LegacyProtocol.js +67 -0
  23. package/src/core/network/protocols/NetworkMessages.js +48 -0
  24. package/src/core/network/protocols/ProtocolInterface.js +31 -0
  25. package/src/core/network/protocols/ProtocolSession.js +59 -0
  26. package/src/core/network/protocols/V1Protocol.js +64 -0
  27. package/src/core/network/protocols/legacy/NetworkMessageRouter.js +84 -0
  28. package/src/core/network/protocols/legacy/handlers/GetRequestHandler.js +53 -0
  29. package/src/core/network/protocols/legacy/handlers/ResponseHandler.js +37 -0
  30. package/src/core/network/{messaging → protocols/legacy}/validators/base/BaseResponse.js +2 -3
  31. package/src/core/network/protocols/shared/handlers/RoleOperationHandler.js +88 -0
  32. package/src/core/network/protocols/shared/handlers/SubnetworkOperationHandler.js +93 -0
  33. package/src/core/network/{messaging → protocols/shared}/handlers/TransferOperationHandler.js +17 -16
  34. package/src/core/network/{messaging → protocols/shared}/handlers/base/BaseOperationHandler.js +10 -15
  35. package/src/core/network/{messaging → protocols/shared}/validators/PartialBootstrapDeployment.js +2 -2
  36. package/src/core/network/{messaging → protocols/shared}/validators/PartialRoleAccess.js +5 -5
  37. package/src/core/network/{messaging → protocols/shared}/validators/PartialTransaction.js +4 -4
  38. package/src/core/network/{messaging → protocols/shared}/validators/PartialTransfer.js +4 -4
  39. package/src/core/network/{messaging → protocols/shared}/validators/base/PartialOperation.js +14 -12
  40. package/src/core/network/protocols/v1/NetworkMessageRouter.js +15 -0
  41. package/src/core/network/services/ConnectionManager.js +5 -5
  42. package/src/core/network/services/MessageOrchestrator.js +2 -2
  43. package/src/core/network/services/TransactionPoolService.js +5 -6
  44. package/src/core/network/services/TransactionRateLimiterService.js +12 -13
  45. package/src/core/network/services/ValidatorObserverService.js +5 -6
  46. package/src/core/state/State.js +3 -5
  47. package/src/index.js +156 -181
  48. package/src/messages/network/v1/NetworkMessageBuilder.js +325 -0
  49. package/src/messages/network/v1/NetworkMessageDirector.js +137 -0
  50. package/src/messages/network/v1/networkMessageFactory.js +12 -0
  51. package/src/messages/state/ApplyStateMessageBuilder.js +661 -0
  52. package/src/messages/state/ApplyStateMessageDirector.js +516 -0
  53. package/src/messages/state/applyStateMessageFactory.js +12 -0
  54. package/src/utils/buffer.js +53 -1
  55. package/src/utils/check.js +1 -1
  56. package/src/utils/cli.js +0 -8
  57. package/src/utils/constants.js +33 -30
  58. package/src/utils/fileUtils.js +13 -0
  59. package/src/utils/normalizers.js +84 -2
  60. package/src/utils/protobuf/network.cjs +840 -0
  61. package/src/utils/protobuf/operationHelpers.js +10 -0
  62. package/src/utils/type.js +26 -0
  63. package/tests/acceptance/v1/balance/balance.test.mjs +1 -2
  64. package/tests/acceptance/v1/broadcast-transaction/broadcast-transaction.test.mjs +26 -30
  65. package/tests/acceptance/v1/health/health.test.mjs +33 -0
  66. package/tests/acceptance/v1/rpc.test.mjs +4 -3
  67. package/tests/acceptance/v1/tx/tx.test.mjs +27 -16
  68. package/tests/acceptance/v1/tx-details/tx-details.test.mjs +26 -12
  69. package/tests/fixtures/check.fixtures.js +33 -32
  70. package/tests/fixtures/networkV1.fixtures.js +85 -0
  71. package/tests/fixtures/protobuf.fixtures.js +109 -25
  72. package/tests/helpers/StateNetworkFactory.js +2 -2
  73. package/tests/helpers/address.js +6 -0
  74. package/tests/helpers/autobaseTestHelpers.js +2 -1
  75. package/tests/helpers/config.js +2 -1
  76. package/tests/helpers/setupApplyTests.js +59 -56
  77. package/tests/unit/messages/messages.test.js +12 -0
  78. package/tests/unit/messages/network/NetworkMessageBuilder.test.js +276 -0
  79. package/tests/unit/messages/network/NetworkMessageDirector.test.js +201 -0
  80. package/tests/unit/messages/state/applyStateMessageBuilder.complete.test.js +521 -0
  81. package/tests/unit/messages/state/applyStateMessageBuilder.partial.test.js +233 -0
  82. package/tests/unit/network/ConnectionManager.test.js +6 -5
  83. package/tests/unit/network/networkModule.test.js +3 -2
  84. package/tests/unit/state/apply/addAdmin/addAdminHappyPathScenario.js +10 -6
  85. package/tests/unit/state/apply/addAdmin/addAdminScenarioHelpers.js +9 -6
  86. package/tests/unit/state/apply/addAdmin/state.apply.addAdmin.test.js +10 -7
  87. package/tests/unit/state/apply/addIndexer/addIndexerScenarioHelpers.js +18 -21
  88. package/tests/unit/state/apply/addWriter/addWriterScenarioHelpers.js +53 -38
  89. package/tests/unit/state/apply/adminRecovery/adminRecoveryScenarioHelpers.js +46 -35
  90. package/tests/unit/state/apply/appendWhitelist/appendWhitelistScenarioHelpers.js +13 -16
  91. package/tests/unit/state/apply/balanceInitialization/balanceInitializationScenarioHelpers.js +17 -11
  92. package/tests/unit/state/apply/banValidator/banValidatorScenarioHelpers.js +11 -12
  93. package/tests/unit/state/apply/bootstrapDeployment/bootstrapDeploymentScenarioHelpers.js +9 -7
  94. package/tests/unit/state/apply/common/commonScenarioHelper.js +15 -14
  95. package/tests/unit/state/apply/common/payload-structure/initializationDisabledScenario.js +9 -4
  96. package/tests/unit/state/apply/disableInitialization/disableInitializationScenarioHelpers.js +17 -11
  97. package/tests/unit/state/apply/removeWriter/removeWriterScenarioHelpers.js +19 -14
  98. package/tests/unit/state/apply/transfer/transferDoubleSpendAcrossValidatorsScenario.js +37 -29
  99. package/tests/unit/state/apply/transfer/transferScenarioHelpers.js +9 -7
  100. package/tests/unit/state/apply/txOperation/txOperationScenarioHelpers.js +11 -9
  101. package/tests/unit/unit.test.js +1 -1
  102. package/tests/unit/utils/buffer/buffer.test.js +62 -1
  103. package/tests/unit/utils/fileUtils/readAddressesFromWhitelistFile.test.js +4 -3
  104. package/tests/unit/utils/fileUtils/readBalanceMigrationFile.test.js +3 -2
  105. package/tests/unit/utils/migrationUtils/validateAddressFromIncomingFile.test.js +3 -2
  106. package/tests/unit/utils/normalizers/normalizers.test.js +469 -0
  107. package/tests/unit/utils/protobuf/operationHelpers.test.js +120 -2
  108. package/tests/unit/utils/type/type.test.js +25 -0
  109. package/tests/unit/utils/utils.test.js +1 -0
  110. package/docs/networking-dualstack-plan.md +0 -75
  111. package/docs/networking-layer-redesign.md +0 -155
  112. package/src/core/network/messaging/NetworkMessages.js +0 -64
  113. package/src/core/network/messaging/handlers/GetRequestHandler.js +0 -113
  114. package/src/core/network/messaging/handlers/ResponseHandler.js +0 -107
  115. package/src/core/network/messaging/handlers/RoleOperationHandler.js +0 -114
  116. package/src/core/network/messaging/handlers/SubnetworkOperationHandler.js +0 -149
  117. package/src/core/network/messaging/routes/NetworkMessageRouter.js +0 -98
  118. package/src/core/network/messaging/validators/AdminResponse.js +0 -58
  119. package/src/core/network/messaging/validators/CustomNodeResponse.js +0 -46
  120. package/src/messages/base/StateBuilder.js +0 -25
  121. package/src/messages/completeStateMessages/CompleteStateMessageBuilder.js +0 -425
  122. package/src/messages/completeStateMessages/CompleteStateMessageDirector.js +0 -252
  123. package/src/messages/completeStateMessages/CompleteStateMessageOperations.js +0 -296
  124. package/src/messages/partialStateMessages/PartialStateMessageBuilder.js +0 -272
  125. package/src/messages/partialStateMessages/PartialStateMessageDirector.js +0 -137
  126. package/src/messages/partialStateMessages/PartialStateMessageOperations.js +0 -138
  127. package/tests/integration/apply/addAdmin/addAdminBasic.test.js +0 -69
  128. package/tests/integration/apply/addAdmin/addAdminRecovery.test.js +0 -126
  129. package/tests/integration/apply/addIndexer.test.js +0 -239
  130. package/tests/integration/apply/addWhitelist.test.js +0 -53
  131. package/tests/integration/apply/addWriter.test.js +0 -245
  132. package/tests/integration/apply/apply.test.js +0 -19
  133. package/tests/integration/apply/banValidator.test.js +0 -116
  134. package/tests/integration/apply/postTx/invalidSubValues.test.js +0 -103
  135. package/tests/integration/apply/postTx/postTx.test.js +0 -196
  136. package/tests/integration/apply/removeIndexer.test.js +0 -132
  137. package/tests/integration/apply/removeWriter.test.js +0 -168
  138. package/tests/integration/apply/transfer.test.js +0 -83
  139. package/tests/integration/integration.test.js +0 -9
  140. package/tests/unit/messageOperations/assembleAddIndexerMessage.test.js +0 -21
  141. package/tests/unit/messageOperations/assembleAddWriterMessage.test.js +0 -17
  142. package/tests/unit/messageOperations/assembleAdminMessage.test.js +0 -68
  143. package/tests/unit/messageOperations/assembleBanWriterMessage.test.js +0 -17
  144. package/tests/unit/messageOperations/assemblePostTransaction.test.js +0 -424
  145. package/tests/unit/messageOperations/assembleRemoveIndexerMessage.test.js +0 -19
  146. package/tests/unit/messageOperations/assembleRemoveWriterMessage.test.js +0 -17
  147. package/tests/unit/messageOperations/assembleWhitelistMessages.test.js +0 -59
  148. package/tests/unit/messageOperations/commonsStateMessageOperationsTest.js +0 -278
  149. package/tests/unit/messageOperations/stateMessageOperations.test.js +0 -19
  150. /package/src/core/network/{messaging → protocols/legacy}/validators/ValidatorResponse.js +0 -0
  151. /package/src/utils/{operations.js → applyOperations.js} +0 -0
@@ -1,107 +0,0 @@
1
- import { NETWORK_MESSAGE_TYPES } from '../../../../utils/constants.js';
2
- import ValidatorResponse from '../validators/ValidatorResponse.js';
3
- import AdminResponse from '../validators/AdminResponse.js';
4
- import CustomNodeResponse from '../validators/CustomNodeResponse.js';
5
- import PeerWallet from 'trac-wallet';
6
-
7
- class ResponseHandler {
8
- #network;
9
- #state;
10
- #responseValidator;
11
- #adminValidator;
12
- #customNodeValidator;
13
-
14
- constructor(network, state, wallet, config) {
15
- this.#network = network;
16
- this.#state = state;
17
- this.#responseValidator = new ValidatorResponse(this.state, wallet, config);
18
- this.#adminValidator = new AdminResponse(this.state, wallet, config);
19
- this.#customNodeValidator = new CustomNodeResponse(this.state, wallet, config);
20
-
21
- }
22
-
23
- get network() {
24
- return this.#network;
25
- }
26
-
27
- get state() {
28
- return this.#state;
29
- }
30
-
31
- get responseValidator() {
32
- return this.#responseValidator;
33
- }
34
-
35
- get adminValidator() {
36
- return this.#adminValidator;
37
- }
38
-
39
- get customNodeValidator() {
40
- return this.#customNodeValidator;
41
- }
42
-
43
- async handle(message, connection, channelString) {
44
- switch (message.op) {
45
- case NETWORK_MESSAGE_TYPES.RESPONSE.VALIDATOR:
46
- await this.#handleValidatorResponse(message, connection, channelString);
47
- break;
48
- case NETWORK_MESSAGE_TYPES.RESPONSE.ADMIN:
49
- await this.#handleAdminResponse(message, connection, channelString);
50
- break;
51
- case NETWORK_MESSAGE_TYPES.RESPONSE.NODE:
52
- await this.#handleCustomNodeResponse(message, connection, channelString);
53
- break;
54
- default:
55
- throw new Error(`Unhandled RESPONSE type: ${message}`);
56
- }
57
- }
58
-
59
- async #handleValidatorResponse(message, connection, channelString) {
60
- const isValid = await this.responseValidator.validate(message, channelString);
61
- if (isValid) {
62
- const validatorAddressString = message.address;
63
- const validatorPublicKey = PeerWallet.decodeBech32m(validatorAddressString);
64
-
65
- if (this.network.validatorConnectionManager.connected(validatorPublicKey)) {
66
- return;
67
- }
68
-
69
- console.log('Validator stream established', validatorAddressString);
70
- this.network.validatorConnectionManager.addValidator(validatorPublicKey, connection)
71
- } else {
72
- throw new Error("Validator response verification failed");
73
- }
74
- }
75
-
76
- async #handleAdminResponse(message, connection, channelString) {
77
- const isValid = await this.adminValidator.validate(message, channelString);
78
- if (isValid) {
79
- const adminEntry = await this.state.getAdminEntry();
80
- const adminPublicKey = PeerWallet.decodeBech32m(adminEntry.address);
81
-
82
- console.log('Admin stream established:', adminEntry.address);
83
- this.network.admin_stream = connection;
84
- this.network.admin = adminPublicKey;
85
- } else {
86
- throw new Error("Admin response verification failed");
87
- }
88
- }
89
-
90
- async #handleCustomNodeResponse(message, connection, channelString) {
91
- const isValid = await this.customNodeValidator.validate(message, channelString);
92
- if (isValid) {
93
- const customNodeAddressString = message.address;
94
- const customNodePublicKey = PeerWallet.decodeBech32m(customNodeAddressString);
95
-
96
- console.log('Custom node stream established:', customNodeAddressString);
97
- this.network.custom_stream = connection;
98
- this.network.custom_node = customNodePublicKey;
99
- } else {
100
- throw new Error("Custom node response verification failed");
101
- }
102
- }
103
-
104
-
105
- }
106
-
107
- export default ResponseHandler;
@@ -1,114 +0,0 @@
1
- import {OperationType} from '../../../../utils/constants.js';
2
- import PartialRoleAccess from "../validators/PartialRoleAccess.js";
3
- import {addressToBuffer} from "../../../state/utils/address.js";
4
- import CompleteStateMessageOperations
5
- from "../../../../messages/completeStateMessages/CompleteStateMessageOperations.js";
6
- import {normalizeHex} from "../../../../utils/helpers.js";
7
- import BaseOperationHandler from './base/BaseOperationHandler.js';
8
-
9
- class RoleOperationHandler extends BaseOperationHandler {
10
- #partialRoleAccessValidator;
11
- #wallet;
12
- #network;
13
- #config;
14
-
15
- /**
16
- * @param {Network} network
17
- * @param {State} state
18
- * @param {PeerWallet} wallet
19
- * @param {TransactionRateLimiterService} rateLimiter
20
- * @param {object} config
21
- **/
22
- constructor(network, state, wallet, rateLimiter, config) {
23
- super(network, state, wallet, rateLimiter, config);
24
- this.#wallet = wallet;
25
- this.#config = config;
26
- this.#network = network;
27
- this.#partialRoleAccessValidator = new PartialRoleAccess(state, wallet ,this.#config)
28
- }
29
-
30
- get partialRoleAccessValidator() {
31
- return this.#partialRoleAccessValidator;
32
- }
33
-
34
- async handleOperation(message, connection) {
35
- const normalizedPartialRoleAccessPayload = this.#normalizePartialRoleAccess(message)
36
- const isValid = await this.partialRoleAccessValidator.validate(normalizedPartialRoleAccessPayload)
37
- let completePayload = null
38
- if (!isValid) {
39
- throw new Error("OperationHandler: partial role access payload validation failed.");
40
- }
41
-
42
- switch (normalizedPartialRoleAccessPayload.type) {
43
- case OperationType.ADD_WRITER:
44
- completePayload = await new CompleteStateMessageOperations(this.#wallet, this.#config).assembleAddWriterMessage(
45
- normalizedPartialRoleAccessPayload.address,
46
- normalizedPartialRoleAccessPayload.rao.tx,
47
- normalizedPartialRoleAccessPayload.rao.txv,
48
- normalizedPartialRoleAccessPayload.rao.iw,
49
- normalizedPartialRoleAccessPayload.rao.in,
50
- normalizedPartialRoleAccessPayload.rao.is,
51
- );
52
- break;
53
- case OperationType.REMOVE_WRITER:
54
- completePayload = await new CompleteStateMessageOperations(this.#wallet, this.#config).assembleRemoveWriterMessage(
55
- normalizedPartialRoleAccessPayload.address,
56
- normalizedPartialRoleAccessPayload.rao.tx,
57
- normalizedPartialRoleAccessPayload.rao.txv,
58
- normalizedPartialRoleAccessPayload.rao.iw,
59
- normalizedPartialRoleAccessPayload.rao.in,
60
- normalizedPartialRoleAccessPayload.rao.is,
61
- );
62
- break;
63
- case OperationType.ADMIN_RECOVERY:
64
- completePayload = await new CompleteStateMessageOperations(this.#wallet, this.#config).assembleAdminRecoveryMessage(
65
- normalizedPartialRoleAccessPayload.address,
66
- normalizedPartialRoleAccessPayload.rao.tx,
67
- normalizedPartialRoleAccessPayload.rao.txv,
68
- normalizedPartialRoleAccessPayload.rao.iw,
69
- normalizedPartialRoleAccessPayload.rao.in,
70
- normalizedPartialRoleAccessPayload.rao.is,
71
- );
72
- console.log("Assembled complete role access operation:", completePayload);
73
- break;
74
- default:
75
- throw new Error("OperationHandler: Assembling complete role access operation failed due to unsupported operation type.");
76
- }
77
-
78
- if (!completePayload) {
79
- throw new Error("OperationHandler: Assembling complete role access operation failed.");
80
- }
81
-
82
- this.#network.transactionPoolService.addTransaction(completePayload)
83
- }
84
-
85
- #normalizePartialRoleAccess(payload) {
86
- if (!payload || typeof payload !== 'object' || !payload.rao) {
87
- throw new Error('Invalid payload for bootstrap deployment normalization.');
88
- }
89
- const {type, address, rao} = payload;
90
- if (
91
- !type ||
92
- !address ||
93
- !rao.tx || !rao.txv || !rao.iw || !rao.in || !rao.is
94
- ) {
95
- throw new Error('Missing required fields in bootstrap deployment payload.');
96
- }
97
-
98
- const normalizedRao = {
99
- tx: normalizeHex(rao.tx),
100
- txv: normalizeHex(rao.txv),
101
- iw: normalizeHex(rao.iw),
102
- in: normalizeHex(rao.in),
103
- is: normalizeHex(rao.is)
104
- };
105
-
106
- return {
107
- type,
108
- address: addressToBuffer(address, this.#config.addressPrefix),
109
- rao: normalizedRao
110
- };
111
- }
112
- }
113
-
114
- export default RoleOperationHandler;
@@ -1,149 +0,0 @@
1
- import BaseOperationHandler from './base/BaseOperationHandler.js';
2
- import CompleteStateMessageOperations
3
- from "../../../../messages/completeStateMessages/CompleteStateMessageOperations.js";
4
- import {
5
- OperationType
6
- } from '../../../../utils/constants.js';
7
- import PartialBootstrapDeployment from "../validators/PartialBootstrapDeployment.js";
8
- import {addressToBuffer} from "../../../state/utils/address.js";
9
- import PartialTransaction from "../validators/PartialTransaction.js";
10
- import {normalizeHex} from "../../../../utils/helpers.js";
11
-
12
-
13
- class SubnetworkOperationHandler extends BaseOperationHandler {
14
- #partialBootstrapDeploymentValidator;
15
- #partialTransactionValidator;
16
- #config;
17
- #wallet;
18
-
19
- /**
20
- * @param {Network} network
21
- * @param {State} state
22
- * @param {PeerWallet} wallet
23
- * @param {TransactionRateLimiterService} rateLimiter
24
- * @param {object} config
25
- **/
26
- constructor(network, state, wallet, rateLimiter, config) {
27
- super(network, state, wallet, rateLimiter, config);
28
- this.#config = config
29
- this.#wallet = wallet
30
- this.#partialBootstrapDeploymentValidator = new PartialBootstrapDeployment(state, wallet, config);
31
- this.#partialTransactionValidator = new PartialTransaction(state, wallet, config);
32
- }
33
-
34
- async handleOperation(payload) {
35
- if (payload.type === OperationType.TX) {
36
- await this.#partialTransactionSubHandler(payload);
37
- } else if (payload.type === OperationType.BOOTSTRAP_DEPLOYMENT) {
38
- await this.#partialBootstrapDeploymentSubHandler(payload);
39
- } else {
40
- throw new Error('Unsupported operation type for SubnetworkOperationHandler');
41
- }
42
- }
43
-
44
- async #partialTransactionSubHandler(payload) {
45
- const normalizedPayload = this.#normalizeTransactionOperation(payload, this.#config);
46
- const isValid = await this.#partialTransactionValidator.validate(normalizedPayload);
47
- if (!isValid) {
48
- throw new Error("SubnetworkHandler: Transaction validation failed.");
49
- }
50
-
51
- const completeTransactionOperation = await new CompleteStateMessageOperations(this.#wallet, this.#config)
52
- .assembleCompleteTransactionOperationMessage(
53
- normalizedPayload.address,
54
- normalizedPayload.txo.tx,
55
- normalizedPayload.txo.txv,
56
- normalizedPayload.txo.iw,
57
- normalizedPayload.txo.in,
58
- normalizedPayload.txo.ch,
59
- normalizedPayload.txo.is,
60
- normalizedPayload.txo.bs,
61
- normalizedPayload.txo.mbs
62
- );
63
- this.network.transactionPoolService.addTransaction(completeTransactionOperation);
64
- }
65
-
66
- async #partialBootstrapDeploymentSubHandler(payload) {
67
- const normalizedPayload = this.#normalizeBootstrapDeployment(payload);
68
- const isValid = await this.#partialBootstrapDeploymentValidator.validate(normalizedPayload);
69
- if (!isValid) {
70
- throw new Error("SubnetworkHandler: Bootstrap deployment validation failed.");
71
- }
72
-
73
- const completeBootstrapDeploymentOperation = await new CompleteStateMessageOperations(this.#wallet, this.#config)
74
- .assembleCompleteBootstrapDeployment(
75
- normalizedPayload.address,
76
- normalizedPayload.bdo.tx,
77
- normalizedPayload.bdo.txv,
78
- normalizedPayload.bdo.bs,
79
- normalizedPayload.bdo.ic,
80
- normalizedPayload.bdo.in,
81
- normalizedPayload.bdo.is,
82
- )
83
- this.network.transactionPoolService.addTransaction(completeBootstrapDeploymentOperation);
84
-
85
- }
86
-
87
- #normalizeBootstrapDeployment(payload) {
88
- if (!payload || typeof payload !== 'object' || !payload.bdo) {
89
- throw new Error('Invalid payload for bootstrap deployment normalization.');
90
- }
91
- const {type, address, bdo} = payload;
92
- if (
93
- type !== OperationType.BOOTSTRAP_DEPLOYMENT ||
94
- !address ||
95
- !bdo.tx || !bdo.bs || !bdo.in || !bdo.is || !bdo.txv
96
- ) {
97
- throw new Error('Missing required fields in bootstrap deployment payload.');
98
- }
99
-
100
- const normalizedBdo = {
101
- tx: normalizeHex(bdo.tx), // Transaction hash
102
- txv: normalizeHex(bdo.txv), // Transaction validity
103
- bs: normalizeHex(bdo.bs), // External bootstrap
104
- ic: normalizeHex(bdo.ic), // Channel
105
- in: normalizeHex(bdo.in), // Nonce
106
- is: normalizeHex(bdo.is) // Signature
107
- };
108
-
109
- return {
110
- type,
111
- address: addressToBuffer(address, this.#config.addressPrefix),
112
- bdo: normalizedBdo
113
- };
114
- }
115
-
116
- #normalizeTransactionOperation(payload) {
117
- if (!payload || typeof payload !== 'object' || !payload.txo) {
118
- throw new Error('Invalid payload for transaction operation normalization.');
119
- }
120
- const {type, address, txo} = payload;
121
- if (
122
- type !== OperationType.TX ||
123
- !address ||
124
- !txo.tx || !txo.txv || !txo.iw || !txo.in ||
125
- !txo.ch || !txo.is || !txo.bs || !txo.mbs
126
- ) {
127
- throw new Error('Missing required fields in transaction operation payload.');
128
- }
129
-
130
- const normalizedTxo = {
131
- tx: normalizeHex(txo.tx), // Transaction hash
132
- txv: normalizeHex(txo.txv), // Transaction validity
133
- iw: normalizeHex(txo.iw), // Writing key
134
- in: normalizeHex(txo.in), // Nonce
135
- ch: normalizeHex(txo.ch), // Content hash
136
- is: normalizeHex(txo.is), // Signature
137
- bs: normalizeHex(txo.bs), // External bootstrap
138
- mbs: normalizeHex(txo.mbs) // MSB bootstrap key
139
- };
140
-
141
- return {
142
- type,
143
- address: addressToBuffer(address, this.#config.addressPrefix),
144
- txo: normalizedTxo
145
- };
146
- }
147
- }
148
-
149
- export default SubnetworkOperationHandler;
@@ -1,98 +0,0 @@
1
- import b4a from "b4a";
2
- import GetRequestHandler from "../handlers/GetRequestHandler.js";
3
- import ResponseHandler from "../handlers/ResponseHandler.js";
4
- import RoleOperationHandler from "../handlers/RoleOperationHandler.js";
5
- import SubnetworkOperationHandler from "../handlers/SubnetworkOperationHandler.js";
6
- import TransferOperationHandler from "../handlers/TransferOperationHandler.js";
7
- import {NETWORK_MESSAGE_TYPES} from '../../../../utils/constants.js';
8
- import * as operation from '../../../../utils/operations.js';
9
- import TransactionRateLimiterService from "../../services/TransactionRateLimiterService.js";
10
- import State from "../../../state/State.js";
11
- import PeerWallet from "trac-wallet";
12
-
13
- class NetworkMessageRouter {
14
- #network;
15
- #handlers;
16
- #config;
17
- #rateLimiter;
18
-
19
- /**
20
- * @param {Network} network
21
- * @param {State} state
22
- * @param {PeerWallet} wallet
23
- * @param {object} config
24
- **/
25
- constructor(network, state, wallet, config) {
26
- this.#network = network;
27
- this.#config = config;
28
- this.#rateLimiter = new TransactionRateLimiterService();
29
- this.#handlers = {
30
- get: new GetRequestHandler(wallet, state),
31
- response: new ResponseHandler(network, state, wallet, this.#config),
32
- roleTransaction: new RoleOperationHandler(network, state, wallet, this.#rateLimiter, this.#config),
33
- subNetworkTransaction: new SubnetworkOperationHandler(network, state, wallet, this.#rateLimiter, this.#config),
34
- tracNetworkTransaction: new TransferOperationHandler(network, state, wallet, this.#rateLimiter, this.#config),
35
- }
36
- }
37
-
38
- async route(incomingMessage, connection, messageProtomux) {
39
- try {
40
- // TODO: Add a check here — only a writer should be able to process the handlers isRoleAccessOperation,isSubnetworkOperation
41
- // and admin nodes until the writers' index is less than 25. OperationType.APPEND_WHITELIST can be processed by only READERS
42
-
43
- const channelString = b4a.toString(this.#config.channel, 'utf8');
44
- if (this.#isGetRequest(incomingMessage)) {
45
- await this.#handlers.get.handle(incomingMessage, messageProtomux, connection, channelString);
46
- this.#network.swarm.leavePeer(connection.remotePublicKey);
47
- }
48
- else if (this.#isResponse(incomingMessage)) {
49
- await this.#handlers.response.handle(incomingMessage, connection, channelString);
50
- this.#network.swarm.leavePeer(connection.remotePublicKey);
51
- }
52
- else if (this.#isRoleAccessOperation(incomingMessage)) {
53
- await this.#handlers.roleTransaction.handle(incomingMessage, connection);
54
- this.#network.swarm.leavePeer(connection.remotePublicKey);
55
-
56
- }
57
- else if (this.#isSubnetworkOperation(incomingMessage)) {
58
- await this.#handlers.subNetworkTransaction.handle(incomingMessage, connection);
59
- this.#network.swarm.leavePeer(connection.remotePublicKey);
60
- }
61
- else if(this.#isTransferOperation(incomingMessage)) {
62
- await this.#handlers.tracNetworkTransaction.handle(incomingMessage, connection);
63
- this.#network.swarm.leavePeer(connection.remotePublicKey);
64
- }
65
- else {
66
- this.#network.swarm.leavePeer(connection.remotePublicKey);
67
- }
68
-
69
- } catch (error) {
70
- throw new Error(`Failed to route message: ${error.message}. Pubkey of requester is ${connection.remotePublicKey ? b4a.toString(connection.remotePublicKey, 'hex') : 'unknown'}`);
71
- }
72
- }
73
-
74
- #isGetRequest(message) {
75
- return Object.values(NETWORK_MESSAGE_TYPES.GET).includes(message);
76
- }
77
-
78
-
79
- #isResponse(message) {
80
- return Object.values(NETWORK_MESSAGE_TYPES.RESPONSE).includes(message.op);
81
- }
82
-
83
- #isRoleAccessOperation(message) {
84
- return operation.isRoleAccess(message.type)
85
- }
86
-
87
- #isSubnetworkOperation(message) {
88
- return operation.isTransaction(message.type) ||
89
- operation.isBootstrapDeployment(message.type)
90
- }
91
-
92
- #isTransferOperation(message) {
93
- return operation.isTransfer(message.type)
94
- }
95
- }
96
-
97
-
98
- export default NetworkMessageRouter;
@@ -1,58 +0,0 @@
1
- import b4a from 'b4a';
2
- import PeerWallet from 'trac-wallet';
3
- import BaseResponse from './base/BaseResponse.js';
4
-
5
- class AdminResponse extends BaseResponse {
6
-
7
- constructor(state, wallet, config) {
8
- super(state, wallet, config);
9
- }
10
-
11
- async validate(message, channelString) {
12
- if (
13
- !this.validatePayload(message) ||
14
- !this.validateIssuerPublicKey(message) ||
15
- !this.validateTimestamp(message) ||
16
- !await this.validateAdminData(message) ||
17
- !await this.validateSignature(message) ||
18
- !this.validateChannel(message, channelString)
19
- ) {
20
- throw new Error("Admin response validation failed");
21
- }
22
-
23
- return true;
24
- }
25
-
26
- validatePayload(message) {
27
- if (!message ||
28
- !message.op ||
29
- !message.wk ||
30
- !message.address ||
31
- !message.nonce ||
32
- !message.channel ||
33
- !message.issuer ||
34
- !message.timestamp) {
35
- throw new Error("Admin response is missing required fields.");
36
- }
37
- return true;
38
- }
39
-
40
- async validateAdminData(message) {
41
- const adminEntry = await this.state.getAdminEntry();
42
- if (!adminEntry) {
43
- throw new Error("Admin entry is null");
44
- }
45
-
46
- const adminPublicKey = PeerWallet.decodeBech32m(adminEntry.address);
47
- const receivedAdminPublicKey = PeerWallet.decodeBech32m(message.address);
48
- const adminWritingKey = b4a.from(message.wk, 'hex');
49
-
50
- if (!b4a.equals(adminPublicKey, receivedAdminPublicKey) || !b4a.equals(adminEntry.wk, adminWritingKey)) {
51
- throw new Error("Admin public key or writing key mismatch in response.");
52
- }
53
-
54
- return true;
55
- }
56
- }
57
-
58
- export default AdminResponse;
@@ -1,46 +0,0 @@
1
- import BaseResponse from './base/BaseResponse.js';
2
-
3
- class CustomNodeResponse extends BaseResponse {
4
-
5
- constructor(state, wallet, config) {
6
- super(state, wallet, config);
7
- }
8
-
9
- async validate(message, channelString) {
10
- if (
11
- !this.validatePayload(message) ||
12
- !this.validateIssuerPublicKey(message) ||
13
- !this.validateTimestamp(message) ||
14
- !await this.validateCustomNodeEntry(message) ||
15
- !await this.validateSignature(message) ||
16
- !this.validateChannel(message, channelString)
17
- ) {
18
- throw new Error("Custom node response validation failed");
19
- }
20
-
21
- return true;
22
- }
23
-
24
- validatePayload(message) {
25
- if (!message ||
26
- !message.op ||
27
- !message.address ||
28
- !message.nonce ||
29
- !message.channel ||
30
- !message.issuer ||
31
- !message.timestamp) {
32
- throw new Error("Custom node response is missing required fields.");
33
- }
34
- return true;
35
- }
36
-
37
- async validateCustomNodeEntry(message) {
38
- const customNodeAddressString = message.address;
39
- const customNodeEntry = await this.state.getNodeEntry(customNodeAddressString);
40
- if (customNodeEntry === null) {
41
- throw new Error("Custom node entry is null - entry is not initialized.");
42
- }
43
- return true;
44
- }
45
- }
46
- export default CustomNodeResponse;
@@ -1,25 +0,0 @@
1
- class StateBuilder {
2
-
3
- constructor() {
4
- if (this.constructor === StateBuilder) {
5
- throw new Error("Builder is an abstract class and cannot be instantiated directly.");
6
- }
7
- }
8
- reset() { throw new Error("Method 'reset()' must be implemented.");}
9
- forOperationType(operationType) {throw new Error("Method 'forOperationType()' must be implemented.");}
10
- withAddress(address) { throw new Error("Method 'withAddress()' must be implemented.");}
11
- withWriterKey(writerKey) { throw new Error("Method 'withWriterKey()' must be implemented.");}
12
- async buildValueAndSign() { throw new Error("Method 'buildValueAndSign()' must be implemented.");}
13
- withIncomingAddress(address) { throw new Error("Method 'withIncomingAddress()' must be implemented.");}
14
- withIncomingWriterKey(writerKey) { throw new Error("Method 'withIncomingWriterKey()' must be implemented.");}
15
- withIncomingNonce(nonce) { throw new Error("Method 'withIncomingNonce()' must be implemented.");}
16
- withContentHash(contentHash) { throw new Error("Method 'withContentHash()' must be implemented.");}
17
- withIncomingSignature(signature) { throw new Error("Method 'withIncomingSignature()' must be implemented.");}
18
- withExternalBootstrap(bootstrapKey) { throw new Error("Method 'withExternalBootstrap()' must be implemented.");}
19
- withMsbBootstrap(msbBootstrap) { throw new Error("Method 'withMsbBootstrap()' must be implemented.");}
20
- withTxHash(txHash) { throw new Error("Method 'withTxHash()' must be implemented.");}
21
- withTxValidity(txValidity) { throw new Error("Method 'withTxValidity()' must be implemented.");}
22
- withAmount(amount) { throw new Error("Method 'withAmount()' must be implemented.");}
23
- }
24
-
25
- export default StateBuilder;