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,7 +1,6 @@
1
1
  import b4a from 'b4a';
2
2
  import PeerWallet from 'trac-wallet';
3
- import { bufferToAddress } from '../../../../state/utils/address.js';
4
- import State from '../../../../state/State.js';
3
+ import State from '../../../../../state/State.js';
5
4
 
6
5
  /*
7
6
  BaseResponse class for handling common validation logic for network responses.
@@ -16,7 +15,7 @@ class BaseResponse {
16
15
  *
17
16
  * @param {State} state
18
17
  * @param {PeerWallet} wallet
19
- * @param {object} config
18
+ * @param {Config} config
20
19
  */
21
20
  constructor(state, wallet, config) {
22
21
  this.#state = state;
@@ -0,0 +1,88 @@
1
+ import {OperationType} from '../../../../../utils/constants.js';
2
+ import PartialRoleAccess from "../validators/PartialRoleAccess.js";
3
+ import BaseOperationHandler from './base/BaseOperationHandler.js';
4
+ import {applyStateMessageFactory} from "../../../../../messages/state/applyStateMessageFactory.js";
5
+ import {safeEncodeApplyOperation} from "../../../../../utils/protobuf/operationHelpers.js";
6
+ import {normalizeRoleAccessOperation} from "../../../../../utils/normalizers.js";
7
+
8
+ class RoleOperationHandler extends BaseOperationHandler {
9
+ #partialRoleAccessValidator;
10
+ #wallet;
11
+ #config;
12
+ #txPoolService;
13
+
14
+ /**
15
+ * @param {State} state
16
+ * @param {PeerWallet} wallet
17
+ * @param {TransactionRateLimiterService} rateLimiter
18
+ * @param {TransactionPoolService} txPoolService
19
+ * @param {Config} config
20
+ **/
21
+ constructor(state, wallet, rateLimiter, txPoolService, config) {
22
+ super(state, wallet, rateLimiter, txPoolService, config);
23
+ this.#wallet = wallet;
24
+ this.#config = config;
25
+ this.#partialRoleAccessValidator = new PartialRoleAccess(state, this.#wallet.address ,this.#config)
26
+ this.#txPoolService = txPoolService;
27
+ }
28
+
29
+ get partialRoleAccessValidator() {
30
+ return this.#partialRoleAccessValidator;
31
+ }
32
+
33
+ async handleOperation(message, connection) {
34
+ const normalizedPartialRoleAccessPayload = normalizeRoleAccessOperation(message, this.#config)
35
+ const isValid = await this.partialRoleAccessValidator.validate(normalizedPartialRoleAccessPayload)
36
+ let completePayload = null
37
+ if (!isValid) {
38
+ throw new Error("OperationHandler: partial role access payload validation failed.");
39
+ }
40
+
41
+ switch (normalizedPartialRoleAccessPayload.type) {
42
+ case OperationType.ADD_WRITER:
43
+ completePayload = await applyStateMessageFactory(this.#wallet, this.#config)
44
+ .buildCompleteAddWriterMessage(
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 applyStateMessageFactory(this.#wallet, this.#config)
55
+ .buildCompleteRemoveWriterMessage(
56
+ normalizedPartialRoleAccessPayload.address,
57
+ normalizedPartialRoleAccessPayload.rao.tx,
58
+ normalizedPartialRoleAccessPayload.rao.txv,
59
+ normalizedPartialRoleAccessPayload.rao.iw,
60
+ normalizedPartialRoleAccessPayload.rao.in,
61
+ normalizedPartialRoleAccessPayload.rao.is,
62
+ )
63
+ break;
64
+ case OperationType.ADMIN_RECOVERY:
65
+
66
+ completePayload = await applyStateMessageFactory(this.#wallet, this.#config)
67
+ .buildCompleteAdminRecoveryMessage(
68
+ normalizedPartialRoleAccessPayload.address,
69
+ normalizedPartialRoleAccessPayload.rao.tx,
70
+ normalizedPartialRoleAccessPayload.rao.txv,
71
+ normalizedPartialRoleAccessPayload.rao.iw,
72
+ normalizedPartialRoleAccessPayload.rao.in,
73
+ normalizedPartialRoleAccessPayload.rao.is,
74
+ )
75
+ break;
76
+ default:
77
+ throw new Error("OperationHandler: Assembling complete role access operation failed due to unsupported operation type.");
78
+ }
79
+
80
+ if (!completePayload) {
81
+ throw new Error("OperationHandler: Assembling complete role access operation failed.");
82
+ }
83
+
84
+ this.#txPoolService.addTransaction(safeEncodeApplyOperation(completePayload))
85
+ }
86
+ }
87
+
88
+ export default RoleOperationHandler;
@@ -0,0 +1,93 @@
1
+ import BaseOperationHandler from './base/BaseOperationHandler.js';
2
+ import {
3
+ OperationType
4
+ } from '../../../../../utils/constants.js';
5
+ import PartialBootstrapDeployment from "../validators/PartialBootstrapDeployment.js";
6
+ import PartialTransaction from "../validators/PartialTransaction.js";
7
+ import {applyStateMessageFactory} from "../../../../../messages/state/applyStateMessageFactory.js";
8
+ import {safeEncodeApplyOperation} from "../../../../../utils/protobuf/operationHelpers.js";
9
+ import {
10
+ normalizeBootstrapDeploymentOperation,
11
+ normalizeTransactionOperation
12
+ } from "../../../../../utils/normalizers.js";
13
+
14
+
15
+ class SubnetworkOperationHandler extends BaseOperationHandler {
16
+ #partialBootstrapDeploymentValidator;
17
+ #partialTransactionValidator;
18
+ #config;
19
+ #wallet;
20
+ #txPoolService;
21
+
22
+ /**
23
+ * @param {State} state
24
+ * @param {PeerWallet} wallet
25
+ * @param {TransactionRateLimiterService} rateLimiter
26
+ * @param {TransactionPoolService} txPoolService
27
+ * @param {Config} config
28
+ **/
29
+ constructor( state, wallet, rateLimiter, txPoolService, config) {
30
+ super(state, wallet, rateLimiter, txPoolService, config);
31
+ this.#config = config;
32
+ this.#wallet = wallet
33
+ this.#partialBootstrapDeploymentValidator = new PartialBootstrapDeployment(state, this.#wallet.address, config);
34
+ this.#partialTransactionValidator = new PartialTransaction(state, this.#wallet.address, config);
35
+ this.#txPoolService = txPoolService;
36
+ }
37
+
38
+ async handleOperation(payload, connection) {
39
+ if (payload.type === OperationType.TX) {
40
+ await this.#partialTransactionSubHandler(payload, connection);
41
+ } else if (payload.type === OperationType.BOOTSTRAP_DEPLOYMENT) {
42
+ await this.#partialBootstrapDeploymentSubHandler(payload, connection);
43
+ } else {
44
+ throw new Error('Unsupported operation type for SubnetworkOperationHandler');
45
+ }
46
+ }
47
+
48
+ async #partialTransactionSubHandler(payload, connection) {
49
+ const normalizedPayload = normalizeTransactionOperation(payload, this.#config);
50
+ const isValid = await this.#partialTransactionValidator.validate(normalizedPayload);
51
+ if (!isValid) {
52
+ throw new Error("SubnetworkHandler: Transaction validation failed.");
53
+ }
54
+
55
+ const completeTransactionOperation = await applyStateMessageFactory(this.#wallet,this.#config)
56
+ .buildCompleteTransactionOperationMessage(
57
+ normalizedPayload.address,
58
+ normalizedPayload.txo.tx,
59
+ normalizedPayload.txo.txv,
60
+ normalizedPayload.txo.iw,
61
+ normalizedPayload.txo.in,
62
+ normalizedPayload.txo.ch,
63
+ normalizedPayload.txo.is,
64
+ normalizedPayload.txo.bs,
65
+ normalizedPayload.txo.mbs
66
+ )
67
+ this.#txPoolService.addTransaction(safeEncodeApplyOperation(completeTransactionOperation));
68
+ }
69
+
70
+ async #partialBootstrapDeploymentSubHandler(payload, connection) {
71
+ const normalizedPayload = normalizeBootstrapDeploymentOperation(payload, this.#config);
72
+ const isValid = await this.#partialBootstrapDeploymentValidator.validate(normalizedPayload);
73
+ if (!isValid) {
74
+ throw new Error("SubnetworkHandler: Bootstrap deployment validation failed.");
75
+ }
76
+
77
+
78
+ const completeBootstrapDeploymentOperation = await applyStateMessageFactory(this.#wallet, this.#config)
79
+ .buildCompleteBootstrapDeploymentMessage(
80
+ normalizedPayload.address,
81
+ normalizedPayload.bdo.tx,
82
+ normalizedPayload.bdo.txv,
83
+ normalizedPayload.bdo.bs,
84
+ normalizedPayload.bdo.ic,
85
+ normalizedPayload.bdo.in,
86
+ normalizedPayload.bdo.is
87
+ )
88
+ this.#txPoolService.addTransaction(safeEncodeApplyOperation(completeBootstrapDeploymentOperation));
89
+
90
+ }
91
+ }
92
+
93
+ export default SubnetworkOperationHandler;
@@ -1,45 +1,46 @@
1
1
  import BaseOperationHandler from './base/BaseOperationHandler.js';
2
- import CompleteStateMessageOperations
3
- from "../../../../messages/completeStateMessages/CompleteStateMessageOperations.js";
4
- import {OperationType} from '../../../../utils/constants.js';
2
+ import {OperationType} from '../../../../../utils/constants.js';
5
3
  import PartialTransfer from "../validators/PartialTransfer.js";
6
- import {normalizeTransferOperation} from "../../../../utils/normalizers.js"
4
+ import {normalizeTransferOperation} from "../../../../../utils/normalizers.js"
5
+ import {applyStateMessageFactory} from "../../../../../messages/state/applyStateMessageFactory.js";
6
+ import {safeEncodeApplyOperation} from "../../../../../utils/protobuf/operationHelpers.js";
7
7
 
8
8
  class TransferOperationHandler extends BaseOperationHandler {
9
9
  #partialTransferValidator;
10
10
  #config;
11
11
  #wallet;
12
+ #txPoolService;
12
13
 
13
14
  /**
14
- * @param {Network} network
15
15
  * @param {State} state
16
16
  * @param {PeerWallet} wallet
17
17
  * @param {TransactionRateLimiterService} rateLimiter
18
- * @param {object} config
18
+ * @param {Config} config
19
19
  **/
20
- constructor(network, state, wallet, rateLimiter, config) {
21
- super(network, state, wallet, rateLimiter, config);
20
+ constructor(state, wallet, rateLimiter, txPoolService, config) {
21
+ super(state, wallet, rateLimiter, txPoolService, config);
22
22
  this.#config = config;
23
23
  this.#wallet = wallet;
24
- this.#partialTransferValidator = new PartialTransfer(state, wallet, this.#config);
24
+ this.#partialTransferValidator = new PartialTransfer(state, this.#wallet.address, this.#config);
25
+ this.#txPoolService = txPoolService;
25
26
  }
26
27
 
27
- async handleOperation(payload) {
28
+ async handleOperation(payload, connection) {
28
29
  if (payload.type !== OperationType.TRANSFER) {
29
30
  throw new Error('Unsupported operation type for TransferOperationHandler');
30
31
  }
31
- await this.#handleTransfer(payload);
32
+ await this.#handleTransfer(payload, connection);
32
33
  }
33
34
 
34
- async #handleTransfer(payload) {
35
+ async #handleTransfer(payload, connection) {
35
36
  const normalizedPayload = normalizeTransferOperation(payload, this.#config);
36
37
  const isValid = await this.#partialTransferValidator.validate(normalizedPayload);
37
38
  if (!isValid) {
38
39
  throw new Error("TransferHandler: Transfer validation failed.");
39
40
  }
40
41
 
41
- const completeTransferOperation = await new CompleteStateMessageOperations(this.#wallet, this.#config)
42
- .assembleCompleteTransferOperationMessage(
42
+ const completeTransferOperation = await applyStateMessageFactory(this.#wallet, this.#config)
43
+ .buildCompleteTransferOperationMessage(
43
44
  normalizedPayload.address,
44
45
  normalizedPayload.tro.tx,
45
46
  normalizedPayload.tro.txv,
@@ -47,9 +48,9 @@ class TransferOperationHandler extends BaseOperationHandler {
47
48
  normalizedPayload.tro.to,
48
49
  normalizedPayload.tro.am,
49
50
  normalizedPayload.tro.is
50
- );
51
+ )
51
52
 
52
- this.network.transactionPoolService.addTransaction(completeTransferOperation);
53
+ this.#txPoolService.addTransaction(safeEncodeApplyOperation(completeTransferOperation));
53
54
  }
54
55
  }
55
56
 
@@ -1,40 +1,35 @@
1
1
  import b4a from 'b4a';
2
- import {MAX_PARTIAL_TX_PAYLOAD_BYTE_SIZE, TRANSACTION_POOL_SIZE} from '../../../../../utils/constants.js';
3
2
 
4
3
  class BaseOperationHandler {
5
- #network;
6
4
  #state;
7
5
  #wallet;
8
6
  #rateLimiter;
7
+ #txPoolService;
9
8
  #config;
10
9
 
11
10
  /**
12
- * @param {Network} network
13
11
  * @param {State} state
14
12
  * @param {PeerWallet} wallet
15
13
  * @param {TransactionRateLimiterService} rateLimiter
16
- * @param {object} config
14
+ * @param {TransactionPoolService} txPoolService
15
+ * @param {Config} config
17
16
  **/
18
- constructor(network, state, wallet, rateLimiter, config) {
17
+ constructor(state, wallet, rateLimiter, txPoolService, config) {
19
18
  if (new.target === BaseOperationHandler) {
20
19
  throw new Error('BaseOperationHandler is abstract and cannot be instantiated directly');
21
20
  }
22
- this.#network = network;
23
21
  this.#state = state;
24
22
  this.#wallet = wallet;
25
23
  this.#rateLimiter = rateLimiter;
24
+ this.#txPoolService = txPoolService;
26
25
  this.#config = config;
27
26
  }
28
27
 
29
- get network() {
30
- return this.#network;
31
- }
32
-
33
28
  async validateBasicRequirements(payload, connection) {
34
29
  // Validate if operation can be processed:
35
30
  // - Non-writable nodes cannot process operations
36
31
  // - Regular indexers cannot process operations
37
- // - Admin-indexer can process operations only when network has less than MAX_WRITERS_FOR_ADMIN_INDEXER_CONNECTION writers
32
+ // - Admin-indexer can process operations only when network has less than maxWritersForAdminIndexerConnection writers
38
33
  const isAllowedToValidate = await this.#state.allowedToValidate(this.#wallet.address);
39
34
  const isAdminAllowedToValidate = await this.#state.isAdminAllowedToValidate();
40
35
  const canValidate = isAllowedToValidate || isAdminAllowedToValidate;
@@ -42,16 +37,16 @@ class BaseOperationHandler {
42
37
  throw new Error('OperationHandler: State is not writable or is an indexer without admin privileges.');
43
38
  }
44
39
 
45
- if (this.#network.transactionPoolService.tx_pool.length >= TRANSACTION_POOL_SIZE) {
40
+ if (this.#txPoolService.tx_pool.length >= this.#config.transactionPoolSize) {
46
41
  throw new Error("OperationHandler: Transaction pool is full, ignoring incoming transaction.");
47
42
  }
48
43
 
49
- if (b4a.byteLength(JSON.stringify(payload)) > MAX_PARTIAL_TX_PAYLOAD_BYTE_SIZE) {
50
- throw new Error(`OperationHandler: Payload size exceeds maximum limit of ${MAX_PARTIAL_TX_PAYLOAD_BYTE_SIZE} bytes by ${b4a.byteLength(JSON.stringify(payload)) - MAX_PARTIAL_TX_PAYLOAD_BYTE_SIZE} bytes.`);
44
+ if (b4a.byteLength(JSON.stringify(payload)) > this.#config.maxPartialTxPayloadByteSize) {
45
+ throw new Error(`OperationHandler: Payload size exceeds maximum limit of ${this.#config.maxPartialTxPayloadByteSize} bytes by ${b4a.byteLength(JSON.stringify(payload)) - this.#config.maxPartialTxPayloadByteSize} bytes.`);
51
46
  }
52
47
 
53
48
  if (!this.#config.disableRateLimit) {
54
- const shouldDisconnect = this.#rateLimiter.handleRateLimit(connection, this.#network);
49
+ const shouldDisconnect = this.#rateLimiter.handleRateLimit(connection);
55
50
  if (shouldDisconnect) {
56
51
  throw new Error(`OperationHandler: Rate limit exceeded for peer ${b4a.toString(connection.remotePublicKey, 'hex')}. Disconnecting...`);
57
52
  }
@@ -1,8 +1,8 @@
1
1
  import PartialOperation from './base/PartialOperation.js';
2
2
 
3
3
  class PartialBootstrapDeployment extends PartialOperation {
4
- constructor(state, wallet , config) {
5
- super(state, wallet , config);
4
+ constructor(state, selfAddress , config) {
5
+ super(state, selfAddress , config);
6
6
  }
7
7
 
8
8
  async validate(payload) {
@@ -1,14 +1,14 @@
1
1
  import b4a from 'b4a';
2
- import {OperationType} from "../../../../utils/constants.js";
3
- import {bufferToAddress} from "../../../state/utils/address.js";
2
+ import {OperationType} from "../../../../../utils/constants.js";
3
+ import {bufferToAddress} from "../../../../state/utils/address.js";
4
4
  import PartialOperation from './base/PartialOperation.js';
5
- import {bufferToBigInt} from "../../../../utils/amountSerialization.js";
5
+ import {bufferToBigInt} from "../../../../../utils/amountSerialization.js";
6
6
 
7
7
  class PartialRoleAccess extends PartialOperation {
8
8
  #config;
9
9
 
10
- constructor(state, wallet, config) {
11
- super(state, wallet, config);
10
+ constructor(state, selfAddress, config) {
11
+ super(state, selfAddress, config);
12
12
  this.#config = config
13
13
  }
14
14
 
@@ -1,13 +1,13 @@
1
1
  import b4a from 'b4a';
2
- import {safeDecodeApplyOperation} from "../../../../utils/protobuf/operationHelpers.js";
3
- import deploymentEntryUtils from "../../../state/utils/deploymentEntry.js";
2
+ import {safeDecodeApplyOperation} from "../../../../../utils/protobuf/operationHelpers.js";
3
+ import deploymentEntryUtils from "../../../../state/utils/deploymentEntry.js";
4
4
  import PartialOperation from './base/PartialOperation.js';
5
5
 
6
6
  class PartialTransaction extends PartialOperation {
7
7
  #config
8
8
 
9
- constructor(state, wallet, config) {
10
- super(state, wallet, config);
9
+ constructor(state, selfAddress, config) {
10
+ super(state, selfAddress, config);
11
11
  this.#config = config
12
12
  }
13
13
 
@@ -1,14 +1,14 @@
1
1
  import PeerWallet from 'trac-wallet';
2
2
 
3
- import {bufferToAddress} from "../../../state/utils/address.js";
4
- import {bufferToBigInt} from "../../../../utils/amountSerialization.js";
3
+ import {bufferToAddress} from "../../../../state/utils/address.js";
4
+ import {bufferToBigInt} from "../../../../../utils/amountSerialization.js";
5
5
  import PartialOperation from './base/PartialOperation.js';
6
6
 
7
7
  class PartialTransfer extends PartialOperation {
8
8
  #config
9
9
 
10
- constructor(state, wallet, config) {
11
- super(state, wallet, config);
10
+ constructor(state, selfAddress, config) {
11
+ super(state, selfAddress, config);
12
12
  this.#config = config
13
13
  }
14
14
 
@@ -1,12 +1,12 @@
1
1
  import b4a from 'b4a';
2
2
  import PeerWallet from 'trac-wallet';
3
- import Check from '../../../../../utils/check.js';
4
- import {bufferToAddress} from "../../../../state/utils/address.js";
5
- import {createMessage} from "../../../../../utils/buffer.js";
6
- import {OperationType} from "../../../../../utils/constants.js";
7
- import {bufferToBigInt} from "../../../../../utils/amountSerialization.js";
8
- import {FEE} from "../../../../state/utils/transaction.js";
9
- import * as operationsUtils from '../../../../../utils/operations.js';
3
+ import Check from '../../../../../../utils/check.js';
4
+ import {bufferToAddress} from "../../../../../state/utils/address.js";
5
+ import {createMessage} from "../../../../../../utils/buffer.js";
6
+ import {OperationType} from "../../../../../../utils/constants.js";
7
+ import {bufferToBigInt} from "../../../../../../utils/amountSerialization.js";
8
+ import {FEE} from "../../../../../state/utils/transaction.js";
9
+ import * as operationsUtils from '../../../../../../utils/applyOperations.js';
10
10
 
11
11
  const MAX_AMOUNT = BigInt('0xffffffffffffffffffffffffffffffff');
12
12
  const FEE_BIGINT = bufferToBigInt(FEE);
@@ -16,15 +16,15 @@ class PartialOperation {
16
16
  #state;
17
17
  #check;
18
18
  #config
19
- #wallet
19
+ #selfAddress
20
20
 
21
- constructor(state, wallet, config) {
21
+ constructor(state, selfAddress, config) {
22
22
  this.#state = state;
23
23
  this.#config = config;
24
24
  this.#check = new Check(this.#config);
25
25
  this.max_amount = MAX_AMOUNT;
26
26
  this.fee = FEE_BIGINT;
27
- this.#wallet = wallet;
27
+ this.#selfAddress = selfAddress;
28
28
  }
29
29
 
30
30
  get state() {
@@ -176,7 +176,7 @@ class PartialOperation {
176
176
  isOperationNotCompleted(payload) {
177
177
  const operationKey = operationsUtils.operationToPayload(payload.type);
178
178
  const operation = payload[operationKey];
179
- const {va, vn, vs} = operation;
179
+ const { va, vn, vs } = operation;
180
180
 
181
181
  const condition = va === undefined && vn === undefined && vs === undefined
182
182
  if (!condition) {
@@ -219,8 +219,10 @@ class PartialOperation {
219
219
  * Flow: Validator -> submits tx with tap-wallet -> RPC-> Validator -validates tx-> REJECT (self-validation)
220
220
  */
221
221
  validateNoSelfValidation(payload) {
222
+ if (!this.#selfAddress) return;
223
+
222
224
  const requesterAddress = bufferToAddress(payload.address, this.#config.addressPrefix);
223
- if (this.#wallet.address === requesterAddress) {
225
+ if (this.#selfAddress === requesterAddress) {
224
226
  throw new Error('Requester address cannot be the same as the validator wallet address.');
225
227
  }
226
228
  }
@@ -0,0 +1,15 @@
1
+ import { MessageHeader } from '../../../../utils/protobuf/network.cjs';
2
+
3
+ class NetworkMessageRouterV1 {
4
+ #config;
5
+
6
+ constructor(config) {
7
+ this.#config = config;
8
+ }
9
+
10
+ async route(incomingMessage) {
11
+ MessageHeader.decode(incomingMessage);
12
+ }
13
+ }
14
+
15
+ export default NetworkMessageRouterV1;
@@ -20,7 +20,7 @@ class ConnectionManager {
20
20
  // As Buffers are objects, we will rely on internal conversions done by JS to compare them.
21
21
  // It would be better to handle these conversions manually by using hex strings as keys to avoid issues
22
22
  /**
23
- * @param {object} config
23
+ * @param {Config} config
24
24
  **/
25
25
  constructor(config) {
26
26
  this.#validators = new Map();
@@ -44,10 +44,10 @@ class ConnectionManager {
44
44
 
45
45
  const target = this.pickRandomValidator(connectedValidators);
46
46
  const entry = this.#validators.get(target);
47
- if (!entry || !entry.connection || !entry.connection.messenger) return null;
47
+ if (!entry || !entry.connection || !entry.connection.protocolSession?.has('legacy')) return null;
48
48
 
49
49
  try {
50
- entry.connection.messenger.send(message);
50
+ entry.connection.protocolSession.send(message);
51
51
  entry.sent = (entry.sent || 0) + 1;
52
52
  } catch (e) {
53
53
  // Swallow individual send errors.
@@ -67,9 +67,9 @@ class ConnectionManager {
67
67
  if (!this.exists(publicKeyHex) || !this.connected(publicKeyHex)) return false; // Fail silently
68
68
 
69
69
  const validator = this.#validators.get(publicKeyHex);
70
- if (!validator || !validator.connection || !validator.connection.messenger) return false;
70
+ if (!validator || !validator.connection || !validator.connection.protocolSession) return false;
71
71
  try {
72
- validator.connection.messenger.send(message);
72
+ validator.connection.protocolSession.send(message);
73
73
  } catch (e) {
74
74
  // Swallow individual send errors.
75
75
  }
@@ -1,5 +1,5 @@
1
1
  import { sleep } from '../../../utils/helpers.js';
2
- import { operationToPayload } from '../../../utils/operations.js';
2
+ import { operationToPayload } from '../../../utils/applyOperations.js';
3
3
  /**
4
4
  * MessageOrchestrator coordinates message submission, retry, and validator management.
5
5
  * It works with ConnectionManager and ledger state to ensure reliable message delivery.
@@ -10,7 +10,7 @@ class MessageOrchestrator {
10
10
  * Attempts to send a message to validators with retries and state checks.
11
11
  * @param {ConnectionManager} connectionManager - The connection manager instance
12
12
  * @param {object} state - The state to look for the message outcome
13
- * @param {object} config - Configuration options:
13
+ * @param {Config} config - Configuration options:
14
14
  */
15
15
  constructor(connectionManager, state, config) {
16
16
  this.connectionManager = connectionManager;
@@ -1,5 +1,5 @@
1
1
  // PoolService.js
2
- import { BATCH_SIZE, PROCESS_INTERVAL_MS } from '../../../utils/constants.js';
2
+ import { BATCH_SIZE } from '../../../utils/constants.js';
3
3
  import Scheduler from '../../../utils/Scheduler.js';
4
4
 
5
5
  class TransactionPoolService {
@@ -12,7 +12,7 @@ class TransactionPoolService {
12
12
  /**
13
13
  * @param {State} state
14
14
  * @param {string} address
15
- * @param {object} config
15
+ * @param {Config} config
16
16
  **/
17
17
  constructor(state, address, config) {
18
18
  this.#state = state;
@@ -37,7 +37,7 @@ class TransactionPoolService {
37
37
  console.info('TransactionPoolService can not start. Wallet is not enabled');
38
38
  return;
39
39
  }
40
- if (this.scheduler && this.scheduler.isRunning) {
40
+ if (this.#scheduler && this.#scheduler.isRunning) {
41
41
  console.info('TransactionPoolService is already started');
42
42
  return;
43
43
  }
@@ -52,7 +52,7 @@ class TransactionPoolService {
52
52
  if (this.#tx_pool.length > 0) {
53
53
  next(0);
54
54
  } else {
55
- next(PROCESS_INTERVAL_MS);
55
+ next(this.#config.processIntervalMs);
56
56
  }
57
57
  } catch (error) {
58
58
  throw new Error(`TransactionPoolService worker error: ${error.message}`);
@@ -60,12 +60,11 @@ class TransactionPoolService {
60
60
  }
61
61
 
62
62
  #createScheduler() {
63
- return new Scheduler((next) => this.#worker(next), PROCESS_INTERVAL_MS);
63
+ return new Scheduler((next) => this.#worker(next), this.#config.processIntervalMs);
64
64
  }
65
65
 
66
66
  async #processTransactions() {
67
67
  const canValidate = await this.#checkValidationPermissions();
68
-
69
68
  if (canValidate && this.#tx_pool.length > 0) {
70
69
  const batch = this.#prepareBatch();
71
70
  await this.#state.append(batch);