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.
- package/CODE_OF_CONDUCT.md +128 -0
- package/README.md +33 -18
- package/docker-compose.yml +1 -0
- package/docs/trac_network_http_api.openapi.yaml +889 -0
- package/msb.mjs +4 -21
- package/package.json +16 -12
- package/proto/network/v1/enums/message_type.proto +16 -0
- package/proto/network/v1/enums/result_code.proto +84 -0
- package/proto/network/v1/messages/broadcast_transaction_request.proto +9 -0
- package/proto/network/v1/messages/broadcast_transaction_response.proto +13 -0
- package/proto/network/v1/messages/liveness_request.proto +8 -0
- package/proto/network/v1/messages/liveness_response.proto +11 -0
- package/proto/network/v1/network_message.proto +22 -0
- package/rpc/handlers.js +163 -90
- package/rpc/routes/v1.js +3 -1
- package/rpc/rpc_server.js +3 -3
- package/rpc/rpc_services.js +45 -31
- package/rpc/utils/helpers.js +82 -51
- package/scripts/generate-protobufs.js +37 -12
- package/src/config/args.js +46 -0
- package/src/config/config.js +99 -5
- package/src/config/env.js +86 -7
- package/src/core/network/Network.js +79 -46
- package/src/core/network/protocols/LegacyProtocol.js +21 -11
- package/src/core/network/protocols/NetworkMessages.js +38 -17
- package/src/core/network/protocols/ProtocolInterface.js +14 -2
- package/src/core/network/protocols/ProtocolSession.js +144 -17
- package/src/core/network/protocols/V1Protocol.js +37 -18
- package/src/core/network/protocols/connectionPolicies.js +88 -0
- package/src/core/network/protocols/legacy/NetworkMessageRouter.js +26 -20
- package/src/core/network/protocols/{shared/handlers/base/BaseOperationHandler.js → legacy/handlers/BaseStateOperationHandler.js} +25 -15
- package/src/core/network/protocols/legacy/handlers/{GetRequestHandler.js → LegacyGetRequestHandler.js} +6 -6
- package/src/core/network/protocols/legacy/handlers/LegacyResponseHandler.js +23 -0
- package/src/core/network/protocols/{shared/handlers/RoleOperationHandler.js → legacy/handlers/LegacyRoleOperationHandler.js} +20 -13
- package/src/core/network/protocols/{shared/handlers/SubnetworkOperationHandler.js → legacy/handlers/LegacySubnetworkOperationHandler.js} +29 -18
- package/src/core/network/protocols/{shared/handlers/TransferOperationHandler.js → legacy/handlers/LegacyTransferOperationHandler.js} +18 -12
- package/src/core/network/protocols/legacy/validators/base/BaseResponse.js +1 -1
- package/src/core/network/protocols/shared/errors/SharedValidatorRejectionError.js +27 -0
- package/src/core/network/protocols/shared/validators/{PartialBootstrapDeployment.js → PartialBootstrapDeploymentValidator.js} +9 -4
- package/src/core/network/protocols/shared/validators/{base/PartialOperation.js → PartialOperationValidator.js} +47 -25
- package/src/core/network/protocols/shared/validators/{PartialRoleAccess.js → PartialRoleAccessValidator.js} +51 -17
- package/src/core/network/protocols/shared/validators/{PartialTransaction.js → PartialTransactionValidator.js} +21 -7
- package/src/core/network/protocols/shared/validators/{PartialTransfer.js → PartialTransferValidator.js} +26 -9
- package/src/core/network/protocols/v1/NetworkMessageRouter.js +91 -7
- package/src/core/network/protocols/v1/V1ProtocolError.js +91 -0
- package/src/core/network/protocols/v1/handlers/V1BaseOperationHandler.js +65 -0
- package/src/core/network/protocols/v1/handlers/V1BroadcastTransactionOperationHandler.js +389 -0
- package/src/core/network/protocols/v1/handlers/V1LivenessOperationHandler.js +87 -0
- package/src/core/network/protocols/v1/validators/V1BaseOperation.js +211 -0
- package/src/core/network/protocols/v1/validators/V1BroadcastTransactionRequest.js +26 -0
- package/src/core/network/protocols/v1/validators/V1BroadcastTransactionResponse.js +276 -0
- package/src/core/network/protocols/v1/validators/V1LivenessRequest.js +15 -0
- package/src/core/network/protocols/v1/validators/V1LivenessResponse.js +17 -0
- package/src/core/network/protocols/v1/validators/V1ValidationSchema.js +210 -0
- package/src/core/network/services/ConnectionManager.js +147 -95
- package/src/core/network/services/MessageOrchestrator.js +152 -28
- package/src/core/network/services/PendingRequestService.js +172 -0
- package/src/core/network/services/TransactionCommitService.js +149 -0
- package/src/core/network/services/TransactionPoolService.js +133 -22
- package/src/core/network/services/TransactionRateLimiterService.js +57 -42
- package/src/core/network/services/ValidatorHealthCheckService.js +127 -0
- package/src/core/network/services/ValidatorObserverService.js +23 -32
- package/src/core/state/State.js +72 -22
- package/src/index.js +8 -5
- package/src/messages/network/v1/NetworkMessageBuilder.js +61 -81
- package/src/messages/network/v1/NetworkMessageDirector.js +16 -50
- package/src/messages/state/ApplyStateMessageBuilder.js +1 -1
- package/src/utils/Scheduler.js +0 -8
- package/src/utils/check.js +1 -1
- package/src/utils/constants.js +68 -19
- package/src/utils/deepEqualApplyPayload.js +40 -0
- package/src/utils/fileUtils.js +13 -0
- package/src/utils/helpers.js +10 -1
- package/src/utils/logger.js +25 -0
- package/src/utils/normalizers.js +38 -0
- package/src/utils/protobuf/networkV1.generated.cjs +2460 -0
- package/src/utils/protobuf/operationHelpers.js +24 -3
- package/src/utils/type.js +26 -0
- package/tests/acceptance/v1/account/account.test.mjs +8 -2
- package/tests/acceptance/v1/balance/balance.test.mjs +1 -2
- package/tests/acceptance/v1/broadcast-transaction/broadcast-transaction.test.mjs +26 -30
- package/tests/acceptance/v1/health/health.test.mjs +33 -0
- package/tests/acceptance/v1/rpc.test.mjs +3 -2
- package/tests/acceptance/v1/tx/tx.test.mjs +50 -17
- package/tests/acceptance/v1/tx-details/tx-details.test.mjs +60 -18
- package/tests/fixtures/check.fixtures.js +33 -32
- package/tests/fixtures/networkV1.fixtures.js +2 -27
- package/tests/fixtures/protobuf.fixtures.js +33 -32
- package/tests/helpers/StateNetworkFactory.js +2 -2
- package/tests/helpers/address.js +6 -0
- package/tests/helpers/autobaseTestHelpers.js +2 -1
- package/tests/helpers/config.js +2 -1
- package/tests/helpers/setupApplyTests.js +6 -10
- package/tests/helpers/transactionPayloads.mjs +2 -2
- package/tests/unit/messages/network/NetworkMessageBuilder.test.js +241 -81
- package/tests/unit/messages/network/NetworkMessageDirector.test.js +225 -81
- package/tests/unit/network/LegacyNetworkMessageRouter.test.js +54 -0
- package/tests/unit/network/ProtocolSession.test.js +127 -0
- package/tests/unit/network/networkModule.test.js +4 -1
- package/tests/unit/network/services/ConnectionManager.test.js +450 -0
- package/tests/unit/network/services/MessageOrchestrator.test.js +445 -0
- package/tests/unit/network/services/PendingRequestService.test.js +431 -0
- package/tests/unit/network/services/TransactionCommitService.test.js +246 -0
- package/tests/unit/network/services/TransactionPoolService.test.js +489 -0
- package/tests/unit/network/services/TransactionRateLimiterService.test.js +139 -0
- package/tests/unit/network/services/ValidatorHealthCheckService.test.js +115 -0
- package/tests/unit/network/services/services.test.js +17 -0
- package/tests/unit/network/utils/v1TestUtils.js +153 -0
- package/tests/unit/network/v1/NetworkMessageRouterV1.test.js +151 -0
- package/tests/unit/network/v1/V1BaseOperation.test.js +356 -0
- package/tests/unit/network/v1/V1BroadcastTransactionOperationHandler.test.js +129 -0
- package/tests/unit/network/v1/V1BroadcastTransactionRequest.test.js +53 -0
- package/tests/unit/network/v1/V1BroadcastTransactionResponse.test.js +512 -0
- package/tests/unit/network/v1/V1LivenessRequest.test.js +32 -0
- package/tests/unit/network/v1/V1LivenessResponse.test.js +45 -0
- package/tests/unit/network/v1/V1ResultCode.test.js +84 -0
- package/tests/unit/network/v1/V1ValidationSchema.test.js +13 -0
- package/tests/unit/network/v1/connectionPolicies.test.js +49 -0
- package/tests/unit/network/v1/handlers/V1BaseOperationHandler.test.js +284 -0
- package/tests/unit/network/v1/handlers/V1BroadcastTransactionOperationHandler.test.js +794 -0
- package/tests/unit/network/v1/handlers/V1LivenessOperationHandler.test.js +193 -0
- package/tests/unit/network/v1/v1.handlers.test.js +15 -0
- package/tests/unit/network/v1/v1.test.js +19 -0
- package/tests/unit/network/v1/v1ValidationSchema/broadcastTransactionRequest.test.js +119 -0
- package/tests/unit/network/v1/v1ValidationSchema/broadcastTransactionResponse.test.js +136 -0
- package/tests/unit/network/v1/v1ValidationSchema/common.test.js +308 -0
- package/tests/unit/network/v1/v1ValidationSchema/livenessRequest.test.js +90 -0
- package/tests/unit/network/v1/v1ValidationSchema/livenessResponse.test.js +133 -0
- package/tests/unit/unit.test.js +2 -2
- package/tests/unit/utils/deepEqualApplyPayload/deepEqualApplyPayload.test.js +102 -0
- package/tests/unit/utils/fileUtils/readAddressesFromWhitelistFile.test.js +4 -3
- package/tests/unit/utils/fileUtils/readBalanceMigrationFile.test.js +3 -2
- package/tests/unit/utils/migrationUtils/validateAddressFromIncomingFile.test.js +3 -2
- package/tests/unit/utils/protobuf/operationHelpers.test.js +2 -4
- package/tests/unit/utils/type/type.test.js +25 -0
- package/tests/unit/utils/utils.test.js +2 -0
- package/.github/workflows/acceptance-tests.yml +0 -42
- package/.github/workflows/publish.yml +0 -33
- package/.github/workflows/unit-tests.yml +0 -40
- package/proto/network.proto +0 -74
- package/src/core/network/protocols/legacy/handlers/ResponseHandler.js +0 -37
- package/src/utils/protobuf/network.cjs +0 -840
- package/tests/unit/network/ConnectionManager.test.js +0 -191
package/src/index.js
CHANGED
|
@@ -44,6 +44,7 @@ import {
|
|
|
44
44
|
getLicenseCountCommand
|
|
45
45
|
} from "./utils/cliCommands.js";
|
|
46
46
|
import {safeEncodeApplyOperation} from "./utils/protobuf/operationHelpers.js";
|
|
47
|
+
import {Config} from "./config/config.js";
|
|
47
48
|
|
|
48
49
|
export class MainSettlementBus extends ReadyResource {
|
|
49
50
|
#store;
|
|
@@ -55,7 +56,7 @@ export class MainSettlementBus extends ReadyResource {
|
|
|
55
56
|
#config
|
|
56
57
|
|
|
57
58
|
/**
|
|
58
|
-
* @param {
|
|
59
|
+
* @param {Config} config
|
|
59
60
|
**/
|
|
60
61
|
constructor(config) {
|
|
61
62
|
super();
|
|
@@ -96,6 +97,8 @@ export class MainSettlementBus extends ReadyResource {
|
|
|
96
97
|
}
|
|
97
98
|
|
|
98
99
|
async _open() {
|
|
100
|
+
await fileUtils.ensureCoresStoreDir(this.#config);
|
|
101
|
+
|
|
99
102
|
if (this.#config.enableWallet) {
|
|
100
103
|
await this.#wallet.initKeyPair(
|
|
101
104
|
this.#config.keyPairPath,
|
|
@@ -301,7 +304,7 @@ export class MainSettlementBus extends ReadyResource {
|
|
|
301
304
|
const success = await this.broadcastPartialTransaction(adminRecoveryMessage);
|
|
302
305
|
|
|
303
306
|
if (!success) {
|
|
304
|
-
throw new Error("Failed to broadcast transaction
|
|
307
|
+
throw new Error("Failed to broadcast transaction. Try again later.");
|
|
305
308
|
}
|
|
306
309
|
|
|
307
310
|
console.info(`Transaction hash: ${adminRecoveryMessage.rao.tx}`);
|
|
@@ -422,7 +425,7 @@ export class MainSettlementBus extends ReadyResource {
|
|
|
422
425
|
const success = await this.broadcastPartialTransaction(assembledMessage);
|
|
423
426
|
|
|
424
427
|
if (!success) {
|
|
425
|
-
throw new Error("Failed to broadcast transaction
|
|
428
|
+
throw new Error("Failed to broadcast transaction. Try again later.");
|
|
426
429
|
}
|
|
427
430
|
|
|
428
431
|
console.info(`Transaction hash: ${assembledMessage.rao.tx}`);
|
|
@@ -456,7 +459,7 @@ export class MainSettlementBus extends ReadyResource {
|
|
|
456
459
|
const success = await this.broadcastPartialTransaction(assembledMessage);
|
|
457
460
|
|
|
458
461
|
if (!success) {
|
|
459
|
-
throw new Error("Failed to broadcast transaction
|
|
462
|
+
throw new Error("Failed to broadcast transaction. Try again later.");
|
|
460
463
|
}
|
|
461
464
|
|
|
462
465
|
console.info(`Transaction hash: ${assembledMessage.rao.tx}`);
|
|
@@ -680,7 +683,7 @@ export class MainSettlementBus extends ReadyResource {
|
|
|
680
683
|
const success = await this.broadcastPartialTransaction(payload);
|
|
681
684
|
|
|
682
685
|
if (!success) {
|
|
683
|
-
throw new Error("Failed to broadcast transaction
|
|
686
|
+
throw new Error("Failed to broadcast transaction. Try again later.");
|
|
684
687
|
}
|
|
685
688
|
|
|
686
689
|
console.info(`Transaction hash: ${payload.bdo.tx}`);
|
|
@@ -8,7 +8,7 @@ import {encodeCapabilities} from "../../../utils/buffer.js";
|
|
|
8
8
|
/**
|
|
9
9
|
* Builder for v1 internal network protocol messages.
|
|
10
10
|
* @param {PeerWallet} wallet
|
|
11
|
-
* @param {
|
|
11
|
+
* @param {Config} config
|
|
12
12
|
*/
|
|
13
13
|
class NetworkMessageBuilder {
|
|
14
14
|
#wallet;
|
|
@@ -19,6 +19,8 @@ class NetworkMessageBuilder {
|
|
|
19
19
|
#issuerAddress;
|
|
20
20
|
#resultCode;
|
|
21
21
|
#data;
|
|
22
|
+
#proof;
|
|
23
|
+
#timestamp_ledger;
|
|
22
24
|
#header;
|
|
23
25
|
#payloadKey;
|
|
24
26
|
#body;
|
|
@@ -26,7 +28,7 @@ class NetworkMessageBuilder {
|
|
|
26
28
|
|
|
27
29
|
/**
|
|
28
30
|
* @param {PeerWallet} wallet
|
|
29
|
-
* @param {
|
|
31
|
+
* @param {Config} config
|
|
30
32
|
*/
|
|
31
33
|
constructor(wallet, config) {
|
|
32
34
|
this.#config = config;
|
|
@@ -85,6 +87,9 @@ class NetworkMessageBuilder {
|
|
|
85
87
|
}
|
|
86
88
|
|
|
87
89
|
setData(data) {
|
|
90
|
+
// case when response have to be empty.
|
|
91
|
+
if (data === undefined || data === null) data = b4a.alloc(0);
|
|
92
|
+
|
|
88
93
|
if (!b4a.isBuffer(data)) {
|
|
89
94
|
throw new Error(`Data must be a buffer.`);
|
|
90
95
|
}
|
|
@@ -92,6 +97,30 @@ class NetworkMessageBuilder {
|
|
|
92
97
|
return this;
|
|
93
98
|
}
|
|
94
99
|
|
|
100
|
+
setProof(proof) {
|
|
101
|
+
if (proof === undefined || proof === null) proof = b4a.alloc(0);
|
|
102
|
+
if (!b4a.isBuffer(proof)) {
|
|
103
|
+
throw new Error(`Proof must be a buffer.`);
|
|
104
|
+
}
|
|
105
|
+
this.#proof = proof;
|
|
106
|
+
return this;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
setTimestampLedger(timestamp) {
|
|
110
|
+
if (timestamp === undefined || timestamp === null) {
|
|
111
|
+
this.#timestamp_ledger = null;
|
|
112
|
+
return this;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
const value = timestamp instanceof Date ? timestamp.getTime() : timestamp;
|
|
116
|
+
if (!Number.isSafeInteger(value) || value < 0) {
|
|
117
|
+
throw new Error('timestamp must be a non-negative safe integer or Date.');
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
this.#timestamp_ledger = value;
|
|
121
|
+
return this;
|
|
122
|
+
}
|
|
123
|
+
|
|
95
124
|
#setHeader() {
|
|
96
125
|
if (!this.#type) throw new Error('Header requires type to be set');
|
|
97
126
|
if (!this.#id) throw new Error('Header requires id to be set');
|
|
@@ -107,76 +136,6 @@ class NetworkMessageBuilder {
|
|
|
107
136
|
return this;
|
|
108
137
|
}
|
|
109
138
|
|
|
110
|
-
async #buildValidatorConnectionRequestPayload() {
|
|
111
|
-
const issuer = this.#issuerAddress
|
|
112
|
-
if (!isAddressValid(issuer, this.#config.addressPrefix)) {
|
|
113
|
-
throw new Error('Issuer address must be a valid TRAC address');
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
if (this.#issuerAddress !== this.#wallet.address) {
|
|
117
|
-
throw new Error('Issuer address must be the signer address');
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
const nonce = PeerWallet.generateNonce();
|
|
121
|
-
const tsBuf = timestampToBuffer(this.#timestamp);
|
|
122
|
-
const idBuf = idToBuffer(this.#id);
|
|
123
|
-
const message = createMessage(
|
|
124
|
-
this.#type,
|
|
125
|
-
idBuf,
|
|
126
|
-
tsBuf,
|
|
127
|
-
addressToBuffer(issuer, this.#config.addressPrefix),
|
|
128
|
-
nonce,
|
|
129
|
-
encodeCapabilities(this.#capabilities),
|
|
130
|
-
);
|
|
131
|
-
const hash = await PeerWallet.blake3(message);
|
|
132
|
-
const signature = this.#wallet.sign(hash);
|
|
133
|
-
|
|
134
|
-
this.#payloadKey = 'validator_connection_request';
|
|
135
|
-
this.#body = {
|
|
136
|
-
issuer_address: issuer,
|
|
137
|
-
nonce,
|
|
138
|
-
signature
|
|
139
|
-
};
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
async #buildValidatorConnectionResponsePayload() {
|
|
143
|
-
const issuer = this.#issuerAddress
|
|
144
|
-
if (!isAddressValid(issuer, this.#config.addressPrefix)) {
|
|
145
|
-
throw new Error('Issuer address must be a valid TRAC address');
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
if (this.#issuerAddress === this.#wallet.address) {
|
|
149
|
-
throw new Error('Issuer address must be the different than the signer address');
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
if (this.#resultCode === null || this.#resultCode === undefined) {
|
|
153
|
-
throw new Error('Result code must be set before building validator connection response');
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
const nonce = PeerWallet.generateNonce();
|
|
157
|
-
const tsBuf = timestampToBuffer(this.#timestamp);
|
|
158
|
-
const idBuf = idToBuffer(this.#id);
|
|
159
|
-
const message = createMessage(
|
|
160
|
-
this.#type,
|
|
161
|
-
idBuf,
|
|
162
|
-
tsBuf,
|
|
163
|
-
addressToBuffer(issuer, this.#config.addressPrefix),
|
|
164
|
-
nonce,
|
|
165
|
-
safeWriteUInt32BE(this.#resultCode, 0),
|
|
166
|
-
encodeCapabilities(this.#capabilities),
|
|
167
|
-
);
|
|
168
|
-
const hash = await PeerWallet.blake3(message);
|
|
169
|
-
const signature = this.#wallet.sign(hash);
|
|
170
|
-
|
|
171
|
-
this.#payloadKey = 'validator_connection_response';
|
|
172
|
-
this.#body = {
|
|
173
|
-
issuer_address: issuer,
|
|
174
|
-
nonce,
|
|
175
|
-
signature,
|
|
176
|
-
result: this.#resultCode
|
|
177
|
-
};
|
|
178
|
-
}
|
|
179
|
-
|
|
180
139
|
async #buildLivenessRequestPayload() {
|
|
181
140
|
const nonce = PeerWallet.generateNonce();
|
|
182
141
|
const tsBuf = timestampToBuffer(this.#timestamp);
|
|
@@ -258,21 +217,50 @@ class NetworkMessageBuilder {
|
|
|
258
217
|
const nonce = PeerWallet.generateNonce();
|
|
259
218
|
const tsBuf = timestampToBuffer(this.#timestamp);
|
|
260
219
|
const idBuf = idToBuffer(this.#id);
|
|
220
|
+
const proof = b4a.isBuffer(this.#proof) ? this.#proof : b4a.alloc(0);
|
|
221
|
+
const hasProof = proof.length > 0;
|
|
222
|
+
const timestamp = Number.isSafeInteger(this.#timestamp_ledger) ? this.#timestamp_ledger : 0;
|
|
223
|
+
const hasTimestamp = timestamp > 0;
|
|
224
|
+
|
|
225
|
+
if (this.#resultCode === ResultCode.OK) {
|
|
226
|
+
if (!hasProof || !hasTimestamp) {
|
|
227
|
+
throw new Error('Result code OK requires non-empty proof and timestamp > 0.');
|
|
228
|
+
}
|
|
229
|
+
} else if (this.#resultCode === ResultCode.TX_ACCEPTED_PROOF_UNAVAILABLE) {
|
|
230
|
+
if (hasProof) {
|
|
231
|
+
throw new Error('Result code TX_ACCEPTED_PROOF_UNAVAILABLE requires empty proof.');
|
|
232
|
+
}
|
|
233
|
+
if (!hasTimestamp) {
|
|
234
|
+
throw new Error('Result code TX_ACCEPTED_PROOF_UNAVAILABLE requires timestamp > 0.');
|
|
235
|
+
}
|
|
236
|
+
} else {
|
|
237
|
+
if (hasProof) {
|
|
238
|
+
throw new Error('Non-OK result code requires empty proof.');
|
|
239
|
+
}
|
|
240
|
+
if (timestamp !== 0) {
|
|
241
|
+
throw new Error('Non-OK result code requires timestamp to be 0, except TX_ACCEPTED_PROOF_UNAVAILABLE.');
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
|
|
261
245
|
const message = createMessage(
|
|
262
246
|
this.#type,
|
|
263
247
|
idBuf,
|
|
264
248
|
tsBuf,
|
|
265
249
|
nonce,
|
|
250
|
+
proof,
|
|
251
|
+
timestampToBuffer(timestamp),
|
|
266
252
|
safeWriteUInt32BE(this.#resultCode, 0),
|
|
267
253
|
encodeCapabilities(this.#capabilities),
|
|
268
254
|
);
|
|
255
|
+
|
|
269
256
|
const hash = await PeerWallet.blake3(message);
|
|
270
257
|
const signature = this.#wallet.sign(hash);
|
|
271
|
-
|
|
272
258
|
this.#payloadKey = 'broadcast_transaction_response';
|
|
273
259
|
this.#body = {
|
|
274
260
|
nonce,
|
|
275
261
|
signature,
|
|
262
|
+
proof,
|
|
263
|
+
timestamp: timestamp,
|
|
276
264
|
result: this.#resultCode
|
|
277
265
|
};
|
|
278
266
|
}
|
|
@@ -281,14 +269,6 @@ class NetworkMessageBuilder {
|
|
|
281
269
|
this.#setHeader();
|
|
282
270
|
|
|
283
271
|
switch (this.#type) {
|
|
284
|
-
case NetworkOperationType.VALIDATOR_CONNECTION_REQUEST: {
|
|
285
|
-
await this.#buildValidatorConnectionRequestPayload();
|
|
286
|
-
break;
|
|
287
|
-
}
|
|
288
|
-
case NetworkOperationType.VALIDATOR_CONNECTION_RESPONSE: {
|
|
289
|
-
await this.#buildValidatorConnectionResponsePayload();
|
|
290
|
-
break;
|
|
291
|
-
}
|
|
292
272
|
case NetworkOperationType.LIVENESS_REQUEST: {
|
|
293
273
|
await this.#buildLivenessRequestPayload();
|
|
294
274
|
break;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {NetworkOperationType} from '../../../utils/constants.js';
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* Director for v1 internal network protocol messages.
|
|
@@ -13,47 +13,6 @@ class NetworkMessageDirector {
|
|
|
13
13
|
this.#builder = builderInstance;
|
|
14
14
|
}
|
|
15
15
|
|
|
16
|
-
/**
|
|
17
|
-
* Build a validator connection request message.
|
|
18
|
-
* @param {string} id
|
|
19
|
-
* @param {string} issuerAddress
|
|
20
|
-
* @param {string[]} capabilities
|
|
21
|
-
* @returns {Promise<object>}
|
|
22
|
-
*/
|
|
23
|
-
async buildValidatorConnectionRequest(id, issuerAddress, capabilities) {
|
|
24
|
-
await this.#builder
|
|
25
|
-
.setType(NetworkOperationType.VALIDATOR_CONNECTION_REQUEST)
|
|
26
|
-
.setId(id)
|
|
27
|
-
.setTimestamp()
|
|
28
|
-
.setIssuerAddress(issuerAddress)
|
|
29
|
-
.setCapabilities(capabilities)
|
|
30
|
-
.buildPayload()
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
return this.#builder.getResult();
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
/**
|
|
37
|
-
* Build a validator connection response message.
|
|
38
|
-
* @param {string} id
|
|
39
|
-
* @param {string} issuerAddress
|
|
40
|
-
* @param {string[]} capabilities
|
|
41
|
-
* @param {number} statusCode
|
|
42
|
-
* @returns {Promise<object>}
|
|
43
|
-
*/
|
|
44
|
-
async buildValidatorConnectionResponse(id, issuerAddress, capabilities, statusCode) {
|
|
45
|
-
await this.#builder
|
|
46
|
-
.setType(NetworkOperationType.VALIDATOR_CONNECTION_RESPONSE)
|
|
47
|
-
.setId(id)
|
|
48
|
-
.setTimestamp()
|
|
49
|
-
.setIssuerAddress(issuerAddress)
|
|
50
|
-
.setCapabilities(capabilities)
|
|
51
|
-
.setResultCode(statusCode)
|
|
52
|
-
.buildPayload()
|
|
53
|
-
|
|
54
|
-
return this.#builder.getResult();
|
|
55
|
-
}
|
|
56
|
-
|
|
57
16
|
/**
|
|
58
17
|
* Build a liveness request message.
|
|
59
18
|
* @param {string} id
|
|
@@ -61,12 +20,11 @@ class NetworkMessageDirector {
|
|
|
61
20
|
* @param {string[]} capabilities
|
|
62
21
|
* @returns {Promise<object>}
|
|
63
22
|
*/
|
|
64
|
-
async buildLivenessRequest(id,
|
|
23
|
+
async buildLivenessRequest(id, capabilities) {
|
|
65
24
|
await this.#builder
|
|
66
25
|
.setType(NetworkOperationType.LIVENESS_REQUEST)
|
|
67
26
|
.setId(id)
|
|
68
27
|
.setTimestamp()
|
|
69
|
-
.setData(data)
|
|
70
28
|
.setCapabilities(capabilities)
|
|
71
29
|
.buildPayload();
|
|
72
30
|
|
|
@@ -76,17 +34,15 @@ class NetworkMessageDirector {
|
|
|
76
34
|
/**
|
|
77
35
|
* Build a liveness response message.
|
|
78
36
|
* @param {string} id
|
|
79
|
-
* @param {Buffer} data
|
|
80
37
|
* @param {string[]} capabilities
|
|
81
38
|
* @param {number} statusCode
|
|
82
39
|
* @returns {Promise<object>}
|
|
83
40
|
*/
|
|
84
|
-
async buildLivenessResponse(id,
|
|
41
|
+
async buildLivenessResponse(id, capabilities, statusCode) {
|
|
85
42
|
await this.#builder
|
|
86
43
|
.setType(NetworkOperationType.LIVENESS_RESPONSE)
|
|
87
44
|
.setId(id)
|
|
88
45
|
.setTimestamp()
|
|
89
|
-
.setData(data)
|
|
90
46
|
.setCapabilities(capabilities)
|
|
91
47
|
.setResultCode(statusCode)
|
|
92
48
|
.buildPayload();
|
|
@@ -115,18 +71,28 @@ class NetworkMessageDirector {
|
|
|
115
71
|
|
|
116
72
|
/**
|
|
117
73
|
* Build a broadcast transaction response message.
|
|
74
|
+
*
|
|
75
|
+
* Allowed payload variants:
|
|
76
|
+
* 1) resultCode === OK - proof must be non-empty and timestamp must be > 0.
|
|
77
|
+
* 2) resultCode === TX_ACCEPTED_PROOF_UNAVAILABLE - proof must be empty and timestamp must be > 0.
|
|
78
|
+
* 3) resultCode !== OK and resultCode !== TX_ACCEPTED_PROOF_UNAVAILABLE - proof must be empty and timestamp must be 0.
|
|
79
|
+
*
|
|
118
80
|
* @param {string} id
|
|
119
81
|
* @param {string[]} capabilities
|
|
120
|
-
* @param {number}
|
|
82
|
+
* @param {number} resultCode
|
|
83
|
+
* @param {Buffer|null|undefined} proof
|
|
84
|
+
* @param {number|Date|null|undefined} timestamp - When transaction has been appended by the validator
|
|
121
85
|
* @returns {Promise<object>}
|
|
122
86
|
*/
|
|
123
|
-
async buildBroadcastTransactionResponse(id, capabilities,
|
|
87
|
+
async buildBroadcastTransactionResponse(id, capabilities, resultCode, proof = null, timestamp = null) {
|
|
124
88
|
await this.#builder
|
|
125
89
|
.setType(NetworkOperationType.BROADCAST_TRANSACTION_RESPONSE)
|
|
126
90
|
.setId(id)
|
|
127
91
|
.setTimestamp()
|
|
128
92
|
.setCapabilities(capabilities)
|
|
129
|
-
.
|
|
93
|
+
.setProof(proof)
|
|
94
|
+
.setTimestampLedger(timestamp)
|
|
95
|
+
.setResultCode(resultCode)
|
|
130
96
|
.buildPayload();
|
|
131
97
|
|
|
132
98
|
return this.#builder.getResult();
|
package/src/utils/Scheduler.js
CHANGED
|
@@ -42,14 +42,6 @@ class Scheduler {
|
|
|
42
42
|
return this.#defaultInterval;
|
|
43
43
|
}
|
|
44
44
|
|
|
45
|
-
get timer() {
|
|
46
|
-
return this.#timer;
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
get currentWorkerRun() {
|
|
50
|
-
return this.#currentWorkerRun;
|
|
51
|
-
}
|
|
52
|
-
|
|
53
45
|
static #validateDelay(delayMs, scope = 'delayMs') {
|
|
54
46
|
const ms = Number(delayMs);
|
|
55
47
|
if (!Number.isFinite(ms) || ms < 0) {
|
package/src/utils/check.js
CHANGED
package/src/utils/constants.js
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
import { OperationType as ApplyOperationType } from './protobuf/applyOperations.cjs';
|
|
2
|
-
import
|
|
2
|
+
import networkV1Generated from './protobuf/networkV1.generated.cjs';
|
|
3
3
|
import b4a from 'b4a'
|
|
4
4
|
// TODO: We are going to have a lot of contstants. It would be good, to separate them into different files.
|
|
5
5
|
|
|
6
|
+
const { MessageType: NetworkMessageType, ResultCode: NetworkResultCode } = networkV1Generated.network.v1;
|
|
7
|
+
|
|
6
8
|
//ATTENTION - THIS IS USED IN THE APPLY FUNCTION!
|
|
7
9
|
export const EntryType = Object.freeze({
|
|
8
10
|
ADMIN: 'admin',
|
|
@@ -34,8 +36,6 @@ export const OperationType = Object.freeze({
|
|
|
34
36
|
});
|
|
35
37
|
|
|
36
38
|
export const NetworkOperationType = Object.freeze({
|
|
37
|
-
VALIDATOR_CONNECTION_REQUEST: NetworkMessageType.MESSAGE_TYPE_VALIDATOR_CONNECTION_REQUEST,
|
|
38
|
-
VALIDATOR_CONNECTION_RESPONSE: NetworkMessageType.MESSAGE_TYPE_VALIDATOR_CONNECTION_RESPONSE,
|
|
39
39
|
LIVENESS_REQUEST: NetworkMessageType.MESSAGE_TYPE_LIVENESS_REQUEST,
|
|
40
40
|
LIVENESS_RESPONSE: NetworkMessageType.MESSAGE_TYPE_LIVENESS_RESPONSE,
|
|
41
41
|
BROADCAST_TRANSACTION_REQUEST: NetworkMessageType.MESSAGE_TYPE_BROADCAST_TRANSACTION_REQUEST,
|
|
@@ -43,12 +43,68 @@ export const NetworkOperationType = Object.freeze({
|
|
|
43
43
|
});
|
|
44
44
|
|
|
45
45
|
export const ResultCode = Object.freeze({
|
|
46
|
+
UNSPECIFIED: NetworkResultCode.RESULT_CODE_UNSPECIFIED,
|
|
46
47
|
OK: NetworkResultCode.RESULT_CODE_OK,
|
|
47
48
|
INVALID_PAYLOAD: NetworkResultCode.RESULT_CODE_INVALID_PAYLOAD,
|
|
48
|
-
UNSUPPORTED_VERSION: NetworkResultCode.RESULT_CODE_UNSUPPORTED_VERSION,
|
|
49
49
|
RATE_LIMITED: NetworkResultCode.RESULT_CODE_RATE_LIMITED,
|
|
50
|
-
TIMEOUT: NetworkResultCode.RESULT_CODE_TIMEOUT,
|
|
51
50
|
SIGNATURE_INVALID: NetworkResultCode.RESULT_CODE_SIGNATURE_INVALID,
|
|
51
|
+
UNEXPECTED_ERROR: NetworkResultCode.RESULT_CODE_UNEXPECTED_ERROR,
|
|
52
|
+
TIMEOUT: NetworkResultCode.RESULT_CODE_TIMEOUT,
|
|
53
|
+
NODE_HAS_NO_WRITE_ACCESS: NetworkResultCode.RESULT_CODE_NODE_HAS_NO_WRITE_ACCESS,
|
|
54
|
+
TX_ACCEPTED_PROOF_UNAVAILABLE: NetworkResultCode.RESULT_CODE_TX_ACCEPTED_PROOF_UNAVAILABLE,
|
|
55
|
+
NODE_OVERLOADED: NetworkResultCode.RESULT_CODE_NODE_OVERLOADED,
|
|
56
|
+
TX_ALREADY_PENDING: NetworkResultCode.RESULT_CODE_TX_ALREADY_PENDING,
|
|
57
|
+
OPERATION_TYPE_UNKNOWN: NetworkResultCode.RESULT_CODE_OPERATION_TYPE_UNKNOWN,
|
|
58
|
+
SCHEMA_VALIDATION_FAILED: NetworkResultCode.RESULT_CODE_SCHEMA_VALIDATION_FAILED,
|
|
59
|
+
REQUESTER_ADDRESS_INVALID: NetworkResultCode.RESULT_CODE_REQUESTER_ADDRESS_INVALID,
|
|
60
|
+
REQUESTER_PUBLIC_KEY_INVALID: NetworkResultCode.RESULT_CODE_REQUESTER_PUBLIC_KEY_INVALID,
|
|
61
|
+
TX_HASH_MISMATCH: NetworkResultCode.RESULT_CODE_TX_HASH_MISMATCH,
|
|
62
|
+
TX_SIGNATURE_INVALID: NetworkResultCode.RESULT_CODE_TX_SIGNATURE_INVALID,
|
|
63
|
+
TX_EXPIRED: NetworkResultCode.RESULT_CODE_TX_EXPIRED,
|
|
64
|
+
TX_ALREADY_EXISTS: NetworkResultCode.RESULT_CODE_TX_ALREADY_EXISTS,
|
|
65
|
+
OPERATION_ALREADY_COMPLETED: NetworkResultCode.RESULT_CODE_OPERATION_ALREADY_COMPLETED,
|
|
66
|
+
REQUESTER_NOT_FOUND: NetworkResultCode.RESULT_CODE_REQUESTER_NOT_FOUND,
|
|
67
|
+
INSUFFICIENT_FEE_BALANCE: NetworkResultCode.RESULT_CODE_INSUFFICIENT_FEE_BALANCE,
|
|
68
|
+
EXTERNAL_BOOTSTRAP_EQUALS_MSB_BOOTSTRAP: NetworkResultCode.RESULT_CODE_EXTERNAL_BOOTSTRAP_EQUALS_MSB_BOOTSTRAP,
|
|
69
|
+
SELF_VALIDATION_FORBIDDEN: NetworkResultCode.RESULT_CODE_SELF_VALIDATION_FORBIDDEN,
|
|
70
|
+
ROLE_NODE_ENTRY_NOT_FOUND: NetworkResultCode.RESULT_CODE_ROLE_NODE_ENTRY_NOT_FOUND,
|
|
71
|
+
ROLE_NODE_ALREADY_WRITER: NetworkResultCode.RESULT_CODE_ROLE_NODE_ALREADY_WRITER,
|
|
72
|
+
ROLE_NODE_NOT_WHITELISTED: NetworkResultCode.RESULT_CODE_ROLE_NODE_NOT_WHITELISTED,
|
|
73
|
+
ROLE_NODE_NOT_WRITER: NetworkResultCode.RESULT_CODE_ROLE_NODE_NOT_WRITER,
|
|
74
|
+
ROLE_NODE_IS_INDEXER: NetworkResultCode.RESULT_CODE_ROLE_NODE_IS_INDEXER,
|
|
75
|
+
ROLE_ADMIN_ENTRY_MISSING: NetworkResultCode.RESULT_CODE_ROLE_ADMIN_ENTRY_MISSING,
|
|
76
|
+
ROLE_INVALID_RECOVERY_CASE: NetworkResultCode.RESULT_CODE_ROLE_INVALID_RECOVERY_CASE,
|
|
77
|
+
ROLE_UNKNOWN_OPERATION: NetworkResultCode.RESULT_CODE_ROLE_UNKNOWN_OPERATION,
|
|
78
|
+
ROLE_INVALID_WRITER_KEY: NetworkResultCode.RESULT_CODE_ROLE_INVALID_WRITER_KEY,
|
|
79
|
+
ROLE_INSUFFICIENT_FEE_BALANCE: NetworkResultCode.RESULT_CODE_ROLE_INSUFFICIENT_FEE_BALANCE,
|
|
80
|
+
MSB_BOOTSTRAP_MISMATCH: NetworkResultCode.RESULT_CODE_MSB_BOOTSTRAP_MISMATCH,
|
|
81
|
+
EXTERNAL_BOOTSTRAP_NOT_DEPLOYED: NetworkResultCode.RESULT_CODE_EXTERNAL_BOOTSTRAP_NOT_DEPLOYED,
|
|
82
|
+
EXTERNAL_BOOTSTRAP_TX_MISSING: NetworkResultCode.RESULT_CODE_EXTERNAL_BOOTSTRAP_TX_MISSING,
|
|
83
|
+
EXTERNAL_BOOTSTRAP_MISMATCH: NetworkResultCode.RESULT_CODE_EXTERNAL_BOOTSTRAP_MISMATCH,
|
|
84
|
+
BOOTSTRAP_ALREADY_EXISTS: NetworkResultCode.RESULT_CODE_BOOTSTRAP_ALREADY_EXISTS,
|
|
85
|
+
TRANSFER_RECIPIENT_ADDRESS_INVALID: NetworkResultCode.RESULT_CODE_TRANSFER_RECIPIENT_ADDRESS_INVALID,
|
|
86
|
+
TRANSFER_RECIPIENT_PUBLIC_KEY_INVALID: NetworkResultCode.RESULT_CODE_TRANSFER_RECIPIENT_PUBLIC_KEY_INVALID,
|
|
87
|
+
TRANSFER_AMOUNT_TOO_LARGE: NetworkResultCode.RESULT_CODE_TRANSFER_AMOUNT_TOO_LARGE,
|
|
88
|
+
TRANSFER_SENDER_NOT_FOUND: NetworkResultCode.RESULT_CODE_TRANSFER_SENDER_NOT_FOUND,
|
|
89
|
+
TRANSFER_INSUFFICIENT_BALANCE: NetworkResultCode.RESULT_CODE_TRANSFER_INSUFFICIENT_BALANCE,
|
|
90
|
+
TRANSFER_RECIPIENT_BALANCE_OVERFLOW: NetworkResultCode.RESULT_CODE_TRANSFER_RECIPIENT_BALANCE_OVERFLOW,
|
|
91
|
+
TX_HASH_INVALID_FORMAT: NetworkResultCode.RESULT_CODE_TX_HASH_INVALID_FORMAT,
|
|
92
|
+
INTERNAL_ENQUEUE_VALIDATION_FAILED: NetworkResultCode.RESULT_CODE_INTERNAL_ENQUEUE_VALIDATION_FAILED,
|
|
93
|
+
TX_COMMITTED_RECEIPT_MISSING: NetworkResultCode.RESULT_CODE_TX_COMMITTED_RECEIPT_MISSING,
|
|
94
|
+
VALIDATOR_RESPONSE_TX_TYPE_INVALID: NetworkResultCode.RESULT_CODE_VALIDATOR_RESPONSE_TX_TYPE_INVALID,
|
|
95
|
+
VALIDATOR_RESPONSE_TX_TYPE_UNKNOWN: NetworkResultCode.RESULT_CODE_VALIDATOR_RESPONSE_TX_TYPE_UNKNOWN,
|
|
96
|
+
VALIDATOR_RESPONSE_TX_TYPE_UNSUPPORTED: NetworkResultCode.RESULT_CODE_VALIDATOR_RESPONSE_TX_TYPE_UNSUPPORTED,
|
|
97
|
+
VALIDATOR_RESPONSE_SCHEMA_INVALID: NetworkResultCode.RESULT_CODE_VALIDATOR_RESPONSE_SCHEMA_INVALID,
|
|
98
|
+
PENDING_REQUEST_MISSING_TX_DATA: NetworkResultCode.RESULT_CODE_PENDING_REQUEST_MISSING_TX_DATA,
|
|
99
|
+
PROOF_PAYLOAD_MISMATCH: NetworkResultCode.RESULT_CODE_PROOF_PAYLOAD_MISMATCH,
|
|
100
|
+
VALIDATOR_WRITER_KEY_NOT_REGISTERED: NetworkResultCode.RESULT_CODE_VALIDATOR_WRITER_KEY_NOT_REGISTERED,
|
|
101
|
+
VALIDATOR_ADDRESS_MISMATCH: NetworkResultCode.RESULT_CODE_VALIDATOR_ADDRESS_MISMATCH,
|
|
102
|
+
VALIDATOR_NODE_ENTRY_NOT_FOUND: NetworkResultCode.RESULT_CODE_VALIDATOR_NODE_ENTRY_NOT_FOUND,
|
|
103
|
+
VALIDATOR_NODE_NOT_WRITER: NetworkResultCode.RESULT_CODE_VALIDATOR_NODE_NOT_WRITER,
|
|
104
|
+
VALIDATOR_WRITER_KEY_MISMATCH: NetworkResultCode.RESULT_CODE_VALIDATOR_WRITER_KEY_MISMATCH,
|
|
105
|
+
VALIDATOR_TX_OBJECT_INVALID: NetworkResultCode.RESULT_CODE_VALIDATOR_TX_OBJECT_INVALID,
|
|
106
|
+
VALIDATOR_VA_MISSING: NetworkResultCode.RESULT_CODE_VALIDATOR_VA_MISSING,
|
|
107
|
+
TX_INVALID_PAYLOAD: NetworkResultCode.RESULT_CODE_TX_INVALID_PAYLOAD
|
|
52
108
|
});
|
|
53
109
|
|
|
54
110
|
// Role managment constants
|
|
@@ -61,6 +117,7 @@ export const EventType = Object.freeze({
|
|
|
61
117
|
WARNING: 'warning',
|
|
62
118
|
VALIDATOR_CONNECTION_READY: 'validator-connection-ready',
|
|
63
119
|
VALIDATOR_CONNECTION_TIMEOUT: 'validator-connection-timeout',
|
|
120
|
+
VALIDATOR_HEALTH_CHECK: 'validator-health-check',
|
|
64
121
|
});
|
|
65
122
|
|
|
66
123
|
// Role managment constants
|
|
@@ -82,13 +139,6 @@ export const TRAC_NAMESPACE = 'TracNetwork';
|
|
|
82
139
|
export const WHITELIST_SLEEP_INTERVAL = 1_000;
|
|
83
140
|
export const BALANCE_MIGRATION_SLEEP_INTERVAL = 500;
|
|
84
141
|
|
|
85
|
-
// Connectivity constants
|
|
86
|
-
export const MAX_PEERS = 64;
|
|
87
|
-
export const MAX_PARALLEL = 64;
|
|
88
|
-
export const MAX_SERVER_CONNECTIONS = Infinity;
|
|
89
|
-
export const MAX_CLIENT_CONNECTIONS = Infinity;
|
|
90
|
-
export const MAX_WRITERS_FOR_ADMIN_INDEXER_CONNECTION = 10;
|
|
91
|
-
|
|
92
142
|
// State
|
|
93
143
|
export const ACK_INTERVAL = 1_000;
|
|
94
144
|
export const AUTOBASE_VALUE_ENCODING = 'binary';
|
|
@@ -115,16 +165,13 @@ export const BOOTSTRAP_HEXSTRING_LENGTH = 64;
|
|
|
115
165
|
|
|
116
166
|
// Pool constants
|
|
117
167
|
export const BATCH_SIZE = 10;
|
|
118
|
-
export const PROCESS_INTERVAL_MS = 50;
|
|
119
|
-
|
|
120
|
-
// Rate limiting constants
|
|
121
|
-
export const CLEANUP_INTERVAL_MS = 120_000;
|
|
122
|
-
export const CONNECTION_TIMEOUT_MS = 60_000;
|
|
123
|
-
export const MAX_TRANSACTIONS_PER_SECOND = 50;
|
|
124
168
|
|
|
125
169
|
// Operation handler constants
|
|
126
170
|
export const MAX_PARTIAL_TX_PAYLOAD_BYTE_SIZE = 3072;
|
|
127
|
-
export const
|
|
171
|
+
export const V1_PROTOCOL_PAYLOAD_MAX_SIZE = 4096;
|
|
172
|
+
|
|
173
|
+
// Transaction Commit Service
|
|
174
|
+
export const TRANSACTION_COMMIT_SERVICE_BUFFER_SIZE = 1500;
|
|
128
175
|
|
|
129
176
|
// Network message constants
|
|
130
177
|
export const NETWORK_MESSAGE_TYPES = Object.freeze({
|
|
@@ -140,3 +187,5 @@ export const NETWORK_MESSAGE_TYPES = Object.freeze({
|
|
|
140
187
|
NODE: 'nodeResponse'
|
|
141
188
|
},
|
|
142
189
|
});
|
|
190
|
+
|
|
191
|
+
export const NETWORK_CAPABILITIES = Object.freeze(["protocols:v1:legacy"]);
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import b4a from 'b4a';
|
|
2
|
+
import _ from 'lodash';
|
|
3
|
+
|
|
4
|
+
export const isDeepEqualApplyPayload = (left, right) => {
|
|
5
|
+
if (left === right) return true;
|
|
6
|
+
|
|
7
|
+
const leftIsBuffer = b4a.isBuffer(left);
|
|
8
|
+
const rightIsBuffer = b4a.isBuffer(right);
|
|
9
|
+
|
|
10
|
+
if (leftIsBuffer || rightIsBuffer) {
|
|
11
|
+
return leftIsBuffer && rightIsBuffer && b4a.equals(left, right);
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
const leftIsArray = Array.isArray(left);
|
|
15
|
+
const rightIsArray = Array.isArray(right);
|
|
16
|
+
|
|
17
|
+
if (leftIsArray || rightIsArray) {
|
|
18
|
+
if (!leftIsArray || !rightIsArray) return false;
|
|
19
|
+
if (left.length !== right.length) return false;
|
|
20
|
+
|
|
21
|
+
for (let i = 0; i < left.length; i++) {
|
|
22
|
+
if (!isDeepEqualApplyPayload(left[i], right[i])) return false;
|
|
23
|
+
}
|
|
24
|
+
return true;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
if (!_.isObject(left) || !_.isObject(right)) return false;
|
|
28
|
+
|
|
29
|
+
const leftKeys = Object.keys(left);
|
|
30
|
+
const rightKeys = Object.keys(right);
|
|
31
|
+
|
|
32
|
+
if (leftKeys.length !== rightKeys.length) return false;
|
|
33
|
+
|
|
34
|
+
for (const key of leftKeys) {
|
|
35
|
+
if (!Object.prototype.hasOwnProperty.call(right, key)) return false;
|
|
36
|
+
if (!isDeepEqualApplyPayload(left[key], right[key])) return false;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
return true;
|
|
40
|
+
};
|
package/src/utils/fileUtils.js
CHANGED
|
@@ -123,6 +123,18 @@ export async function getAllMigrationFiles(migrationDirectory = BALANCE_MIGRATED
|
|
|
123
123
|
}
|
|
124
124
|
}
|
|
125
125
|
|
|
126
|
+
export async function ensureCoresStoreDir(config) {
|
|
127
|
+
try {
|
|
128
|
+
// const storesDirectoryStats = await fs.promises.stat(config.storesDirectory);
|
|
129
|
+
// if (!storesDirectoryStats.isDirectory()) {
|
|
130
|
+
// throw new Error(`Stores directory path is not a directory: ${config.storesDirectory}`);
|
|
131
|
+
// }
|
|
132
|
+
await fs.promises.mkdir(config.storesFullPath, { recursive: true });
|
|
133
|
+
} catch (err) {
|
|
134
|
+
throw new Error(`Failed to ensure corestore directory: ${err.message}`);
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
|
|
126
138
|
export async function validateBalanceMigrationData(addresses) {
|
|
127
139
|
const migrationFiles = await getAllMigrationFiles(BALANCE_MIGRATED_DIR);
|
|
128
140
|
const addressSet = new Set(addresses.map(a => a.address));
|
|
@@ -197,6 +209,7 @@ export default {
|
|
|
197
209
|
readAddressesFromWhitelistFile,
|
|
198
210
|
readBalanceMigrationFile,
|
|
199
211
|
getAllMigrationFiles,
|
|
212
|
+
ensureCoresStoreDir,
|
|
200
213
|
validateBalanceMigrationData,
|
|
201
214
|
validateWhitelistMigrationData,
|
|
202
215
|
getNextMigrationNumber,
|
package/src/utils/helpers.js
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import b4a from "b4a";
|
|
2
|
+
import PeerWallet from "trac-wallet";
|
|
2
3
|
import {bufferToAddress} from "../core/state/utils/address.js";
|
|
3
4
|
import { EntryType } from "./constants.js";
|
|
4
|
-
|
|
5
|
+
import { v7 as uuidv7 } from 'uuid';
|
|
5
6
|
//TODO: change file name or split functions below into multiple files (Remember to update imports and tests accordingly)
|
|
6
7
|
|
|
7
8
|
export function isHexString(string) {
|
|
@@ -95,3 +96,11 @@ export function isTransactionRecordPut(entry) {
|
|
|
95
96
|
const is64 = entry.key.length === 64;
|
|
96
97
|
return isPut && isHex && is64;
|
|
97
98
|
}
|
|
99
|
+
|
|
100
|
+
export function generateUUID() {
|
|
101
|
+
return uuidv7();
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
export function publicKeyToAddress(publicKey, config) {
|
|
105
|
+
return PeerWallet.encodeBech32m(config.addressPrefix, b4a.isBuffer(publicKey) ? publicKey : b4a.from(publicKey, typeof publicKey === 'string' ? 'hex' : undefined));
|
|
106
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
export class Logger {
|
|
2
|
+
#config
|
|
3
|
+
constructor(config) {
|
|
4
|
+
this.#config = config;
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
info(message) {
|
|
8
|
+
console.log("i: " + message);
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
debug(message) {
|
|
12
|
+
if (this.#config.debug) {
|
|
13
|
+
console.debug("d: " + message);
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
error(message) {
|
|
18
|
+
console.error("e: " + message);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
warn(message) {
|
|
22
|
+
console.warn("w: " + message);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
}
|