trac-msb 0.1.76 → 0.1.77-msb-r2-dev.1
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/.github/workflows/CI.yml +40 -0
- package/README.md +12 -0
- package/docs/TIP/TIP-000.md +49 -0
- package/docs/TIP/TIP-001.md +220 -0
- package/migration/.gitkeep +0 -0
- package/msb.mjs +37 -6
- package/package.json +33 -9
- package/proto/applyOperations.proto +117 -0
- package/rpc/constants.mjs +2 -0
- package/rpc/cors.mjs +15 -0
- package/rpc/create_server.mjs +39 -0
- package/rpc/handlers.mjs +167 -0
- package/rpc/router.mjs +23 -0
- package/rpc/rpc_server.mjs +10 -0
- package/rpc/utils/helpers.mjs +67 -0
- package/scripts/generate-protobufs.js +42 -0
- package/src/core/network/Network.js +259 -0
- package/src/core/network/messaging/NetworkMessages.js +63 -0
- package/src/core/network/messaging/handlers/GetRequestHandler.js +112 -0
- package/src/core/network/messaging/handlers/OperationHandler.js +114 -0
- package/src/core/network/messaging/handlers/ResponseHandler.js +112 -0
- package/src/core/network/messaging/handlers/SubnetworkOperationHandler.js +143 -0
- package/src/core/network/messaging/handlers/TransferOperationHandler.js +52 -0
- package/src/core/network/messaging/handlers/WhitelistedEventHandler.js +88 -0
- package/src/core/network/messaging/handlers/base/BaseOperationHandler.js +63 -0
- package/src/core/network/messaging/routes/NetworkMessageRouter.js +104 -0
- package/src/core/network/messaging/validators/AdminResponse.js +62 -0
- package/src/core/network/messaging/validators/CustomNodeResponse.js +49 -0
- package/src/core/network/messaging/validators/PartialBootstrapDeployment.js +174 -0
- package/src/core/network/messaging/validators/PartialRoleAccess.js +229 -0
- package/src/core/network/messaging/validators/PartialTransaction.js +206 -0
- package/src/core/network/messaging/validators/PartialTransfer.js +205 -0
- package/src/core/network/messaging/validators/ValidatorResponse.js +72 -0
- package/src/core/network/messaging/validators/WhitelistEvent.js +117 -0
- package/src/core/network/messaging/validators/base/BaseResponse.js +92 -0
- package/src/core/network/messaging/validators/base/PartialOperation.js +8 -0
- package/src/core/network/services/PoolService.js +43 -0
- package/src/core/network/services/TransactionRateLimiterService.js +121 -0
- package/src/core/network/services/ValidatorObserverService.js +97 -0
- package/src/core/state/State.js +3643 -0
- package/src/core/state/utils/address.js +71 -0
- package/src/core/state/utils/adminEntry.js +67 -0
- package/src/core/state/utils/balance.js +302 -0
- package/src/core/state/utils/deploymentEntry.js +75 -0
- package/src/core/state/utils/indexerEntry.js +105 -0
- package/src/core/state/utils/lengthEntry.js +94 -0
- package/src/core/state/utils/nodeEntry.js +346 -0
- package/src/core/state/utils/roles.js +53 -0
- package/src/core/state/utils/transaction.js +117 -0
- package/src/index.js +996 -815
- package/src/messages/base/StateBuilder.js +25 -0
- package/src/messages/completeStateMessages/CompleteStateMessageBuilder.js +401 -0
- package/src/messages/completeStateMessages/CompleteStateMessageDirector.js +252 -0
- package/src/messages/completeStateMessages/CompleteStateMessageOperations.js +307 -0
- package/src/messages/partialStateMessages/PartialStateMessageBuilder.js +271 -0
- package/src/messages/partialStateMessages/PartialStateMessageDirector.js +137 -0
- package/src/messages/partialStateMessages/PartialStateMessageOperations.js +131 -0
- package/src/utils/amountSerialization.js +110 -0
- package/src/utils/buffer.js +62 -0
- package/src/utils/check.js +475 -114
- package/src/utils/cli.js +106 -0
- package/src/utils/constants.js +92 -41
- package/src/utils/crypto.js +11 -0
- package/src/utils/fileUtils.js +79 -14
- package/src/utils/helpers.js +99 -0
- package/src/utils/normalizers.js +85 -0
- package/src/utils/operations.js +95 -0
- package/src/utils/protobuf/applyOperations.cjs +1373 -0
- package/src/utils/protobuf/operationHelpers.js +50 -0
- package/src/utils/transactionUtils.js +58 -0
- package/test/acceptance/rpc.test.mjs +145 -0
- package/test/all.test.js +10 -8
- package/test/apply/addAdmin/addAdminBasic.test.js +68 -0
- package/test/apply/addAdmin/addAdminRecovery.test.js +117 -0
- package/test/apply/addIndexer.test.js +261 -0
- package/test/apply/addWhitelist.test.js +53 -0
- package/test/apply/addWriter.test.js +396 -0
- package/test/apply/apply.test.js +17 -0
- package/test/apply/banValidator.test.js +122 -0
- package/test/apply/postTx.test.js +227 -0
- package/test/apply/removeIndexer.test.js +142 -0
- package/test/apply/removeWriter.test.js +215 -0
- package/test/buffer/buffer.test.js +190 -0
- package/test/check/adminControlOperation.test.js +156 -0
- package/test/check/balanceInitializationOperation.test.js +54 -0
- package/test/check/bootstrapDeploymentOperation.test.js +105 -0
- package/test/check/check.test.js +17 -0
- package/test/check/common.test.js +418 -0
- package/test/check/coreAdminOperation.test.js +95 -0
- package/test/check/roleAccessOperation.test.js +254 -0
- package/test/check/transactionOperation.test.js +107 -0
- package/test/check/transferOperation.test.js +102 -0
- package/test/fileUtils/readBalanceMigrationFile.test.js +62 -0
- package/test/fileUtils/readPublicKeysFromFile.test.js +53 -0
- package/test/fixtures/apply.fixtures.js +41 -0
- package/test/fixtures/assembleMessage.fixtures.js +40 -0
- package/test/fixtures/check.fixtures.js +427 -0
- package/test/fixtures/protobuf.fixtures.js +289 -0
- package/test/functions/amountSerialization.test.js +237 -0
- package/test/functions/applyOperations.test.js +91 -0
- package/test/functions/createHash.test.js +15 -0
- package/test/functions/functions.test.js +14 -0
- package/test/functions/isHexString.test.js +12 -0
- package/test/functions/normalizeHex.test.js +82 -0
- package/test/messageOperations/assembleAddIndexerMessage.test.js +21 -0
- package/test/messageOperations/assembleAddWriterMessage.test.js +16 -0
- package/test/messageOperations/assembleAdminMessage.test.js +69 -0
- package/test/messageOperations/assembleBanWriterMessage.test.js +16 -0
- package/test/messageOperations/assemblePostTransaction.test.js +442 -0
- package/test/messageOperations/assembleRemoveIndexerMessage.test.js +19 -0
- package/test/messageOperations/assembleRemoveWriterMessage.test.js +17 -0
- package/test/messageOperations/assembleWhitelistMessages.test.js +58 -0
- package/test/messageOperations/commonsStateMessageOperationsTest.js +277 -0
- package/test/messageOperations/stateMessageOperations.test.js +19 -0
- package/test/protobuf/protobuf.test.js +185 -0
- package/test/state/State.test.js +80 -0
- package/test/state/stateTestUtils.js +24 -0
- package/test/state/stateTests.test.js +23 -0
- package/test/state/utils/address.test.js +63 -0
- package/test/state/utils/adminEntry.test.js +51 -0
- package/test/state/utils/balance.test.js +320 -0
- package/test/state/utils/indexerEntry.test.js +83 -0
- package/test/state/utils/lengthEntry.test.js +54 -0
- package/test/state/utils/nodeEntry.test.js +298 -0
- package/test/state/utils/roles.test.js +44 -0
- package/test/state/utils/transaction.test.js +97 -0
- package/test/utils/regexHelper.js +3 -0
- package/test/utils/setupApplyTests.js +496 -0
- package/whitelist/.gitkeep +0 -0
- package/Whitelist/pubkeys.csv +0 -1
- package/dump/LICENSE +0 -201
- package/dump/NOTICE +0 -17
- package/dump/README.md +0 -66
- package/dump/Whitelist/pubkeys.csv +0 -1
- package/dump/msb.mjs +0 -14
- package/dump/package.json +0 -40
- package/dump/src/index.js +0 -1005
- package/dump/src/network.js +0 -295
- package/dump/src/utils/check.js +0 -163
- package/dump/src/utils/constants.js +0 -63
- package/dump/src/utils/fileUtils.js +0 -31
- package/dump/src/utils/functions.js +0 -70
- package/dump/src/utils/msgUtils.js +0 -137
- package/dump/test/all.test.js +0 -18
- package/dump/test/check.test.js +0 -21
- package/dump/test/fileUtils.test.js +0 -16
- package/dump/test/functions.test.js +0 -22
- package/src/network.js +0 -295
- package/src/utils/functions.js +0 -70
- package/src/utils/msgUtils.js +0 -137
- package/test/check.test.js +0 -21
- package/test/fileUtils.test.js +0 -16
- package/test/functions.test.js +0 -22
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
name: MSB-CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches:
|
|
6
|
+
- main
|
|
7
|
+
pull_request:
|
|
8
|
+
branches:
|
|
9
|
+
- '*'
|
|
10
|
+
workflow_dispatch:
|
|
11
|
+
|
|
12
|
+
concurrency:
|
|
13
|
+
group: ${{ github.workflow }}-${{ github.ref }}
|
|
14
|
+
cancel-in-progress: true
|
|
15
|
+
|
|
16
|
+
jobs:
|
|
17
|
+
tests:
|
|
18
|
+
runs-on: ${{ matrix.os }}
|
|
19
|
+
|
|
20
|
+
strategy:
|
|
21
|
+
matrix:
|
|
22
|
+
node-version: [lts/*]
|
|
23
|
+
os: [ubuntu-latest, macos-latest, windows-latest]
|
|
24
|
+
steps:
|
|
25
|
+
- uses: actions/checkout@v4
|
|
26
|
+
- name: Use Node.js ${{ matrix.node-version }}
|
|
27
|
+
uses: actions/setup-node@v3
|
|
28
|
+
with:
|
|
29
|
+
node-version: ${{ matrix.node-version }}
|
|
30
|
+
cache: 'npm'
|
|
31
|
+
- name: Install dependencies
|
|
32
|
+
run: npm ci
|
|
33
|
+
- name: Run node tests
|
|
34
|
+
run: npm run test:node
|
|
35
|
+
- name: Install bare
|
|
36
|
+
run: npm i -g bare
|
|
37
|
+
- name: Run bare tests
|
|
38
|
+
run: npm run test:bare
|
|
39
|
+
- name: Run rpc acceptance tests
|
|
40
|
+
run: npm run test:acceptance
|
package/README.md
CHANGED
|
@@ -20,9 +20,21 @@ While the MSB supports native node-js, it is encouraged to use Pear:
|
|
|
20
20
|
cd main_settlement_bus
|
|
21
21
|
npm install -g pear
|
|
22
22
|
npm install
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
You can run the node in two modes:
|
|
26
|
+
1. Regular node (validator/indexer):
|
|
27
|
+
```js
|
|
23
28
|
pear run . store1
|
|
24
29
|
```
|
|
25
30
|
|
|
31
|
+
2. Admin node (access to administrative commands):
|
|
32
|
+
```js
|
|
33
|
+
pear run . admin
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
The admin mode provides access to additional commands such as `/add_admin`, `/add_whitelist`, `/balance_migration`, `/disable_initialization`, `/add_indexer`, `/remove_indexer`, and `/ban_writer`. These commands are only visible and available when running in admin mode.
|
|
37
|
+
|
|
26
38
|
**Deploy Bootstrap (admin):**
|
|
27
39
|
|
|
28
40
|
- Choose option 1)
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
# TIP-NNN: _Title_
|
|
2
|
+
|
|
3
|
+
## Metadata
|
|
4
|
+
- **TIP**: NNN
|
|
5
|
+
- **Title**: _Title_
|
|
6
|
+
- **Author(s)**: _Author_
|
|
7
|
+
- **Type**: CORE | STATE | CONSENSUS | NETWORK | SECURITY | VALIDATION | API | OPERATIONS | TOOLS | META
|
|
8
|
+
- **Status**: Draft | Review | Accepted | Rejected | Final | Superseded
|
|
9
|
+
- **Created**: YYYY-MM-DD
|
|
10
|
+
- **Last Updated**: YYYY-MM-DD
|
|
11
|
+
|
|
12
|
+
## Summary
|
|
13
|
+
_Provide a clear and concise explanation of the proposal_
|
|
14
|
+
|
|
15
|
+
## Motivation
|
|
16
|
+
_Explain the why behind this change_
|
|
17
|
+
|
|
18
|
+
## Specification
|
|
19
|
+
_Detailed technical specification_
|
|
20
|
+
|
|
21
|
+
## Reference Implementation
|
|
22
|
+
_Code examples or links_
|
|
23
|
+
|
|
24
|
+
## Benefits
|
|
25
|
+
_List expected benefits_
|
|
26
|
+
|
|
27
|
+
## Compatibility
|
|
28
|
+
_Describe compatibility concerns_
|
|
29
|
+
|
|
30
|
+
## Validation / Testing Plan
|
|
31
|
+
_Describe how this will be tested_
|
|
32
|
+
|
|
33
|
+
## Security Considerations
|
|
34
|
+
_List security implications_
|
|
35
|
+
|
|
36
|
+
## References
|
|
37
|
+
_List related documentation_
|
|
38
|
+
|
|
39
|
+
[//]: # (Type Legend:)
|
|
40
|
+
[//]: # (CORE: Fundamental changes to system architecture)
|
|
41
|
+
[//]: # (STATE: Changes to state management and storage mechanisms)
|
|
42
|
+
[//]: # (CONSENSUS: Changes to consensus mechanisms)
|
|
43
|
+
[//]: # (NETWORK: Changes to network protocol and communication)
|
|
44
|
+
[//]: # (SECURITY: Security and validation improvements)
|
|
45
|
+
[//]: # (VALIDATION: Changes to operation validation logic)
|
|
46
|
+
[//]: # (API: Changes to API interfaces)
|
|
47
|
+
[//]: # (OPERATIONS: Changes to business operations)
|
|
48
|
+
[//]: # (TOOLS: Developer and administrative tools)
|
|
49
|
+
[//]: # (META: Changes to processes, documentation, or standards)
|
|
@@ -0,0 +1,220 @@
|
|
|
1
|
+
# TRAC-IMPROVMENT-PROPOSALS-001: State handlers refactoring
|
|
2
|
+
|
|
3
|
+
## Status
|
|
4
|
+
- **TIP**: 001
|
|
5
|
+
- **Title**: State handlers refactoring
|
|
6
|
+
- **Authors**: b-garbacz
|
|
7
|
+
- **Type**: Technical design proposal
|
|
8
|
+
- **Status**: Draft
|
|
9
|
+
- **Created**: 2023-09-26
|
|
10
|
+
- **Last Updated**: 2023-09-26
|
|
11
|
+
|
|
12
|
+
## Summary
|
|
13
|
+
Proposal to refactor the current monolithic State handlers into a modular, maintainable architecture using the Handler pattern.
|
|
14
|
+
|
|
15
|
+
## Motivation
|
|
16
|
+
Current implementation in `State.js` faces several challenges:
|
|
17
|
+
- Large file size (~3000 lines) making it hard to maintain
|
|
18
|
+
- Duplicate code across handlers
|
|
19
|
+
- Difficult to test individual handler logic
|
|
20
|
+
- Complex error handling spread across methods
|
|
21
|
+
- Limited code reuse between similar operations
|
|
22
|
+
|
|
23
|
+
## Specification
|
|
24
|
+
|
|
25
|
+
> **Note**: The following code snippets are abstract examples illustrating the refactoring concept. Any feedback for their improvement is crucial for creating more maintainable code.
|
|
26
|
+
|
|
27
|
+
### 1. Core Components
|
|
28
|
+
|
|
29
|
+
#### 1.1 Base Handler
|
|
30
|
+
```javascript
|
|
31
|
+
export class BaseHandler {
|
|
32
|
+
#state;
|
|
33
|
+
#enableTxLogs;
|
|
34
|
+
|
|
35
|
+
constructor(state, enableTxLogs = true) {
|
|
36
|
+
this.#state = state;
|
|
37
|
+
this.#enableTxLogs = enableTxLogs;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
async handle(op, view, base, node, batch) {
|
|
41
|
+
return null;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
#safeLog(operationType, message, validatorWk) {
|
|
45
|
+
if (this.#enableTxLogs) {
|
|
46
|
+
this.#state.safeLogApply(operationType, message, validatorWk);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
async #validateAddressFormat(address, operationType, nodeKey) {
|
|
51
|
+
const addressString = addressUtils.bufferToAddress(address);
|
|
52
|
+
if (addressString === null) {
|
|
53
|
+
this.#safeLog(operationType, "Invalid address format.", nodeKey);
|
|
54
|
+
return null;
|
|
55
|
+
}
|
|
56
|
+
return addressString;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
#### 1.2 Handler Factory
|
|
62
|
+
```javascript
|
|
63
|
+
export class HandlerFactory {
|
|
64
|
+
#handlers;
|
|
65
|
+
|
|
66
|
+
constructor(state) {
|
|
67
|
+
this.#handlers = new Map();
|
|
68
|
+
this.initializeHandlers(state);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
getHandler(operationType) {
|
|
72
|
+
const handler = this.#handlers.get(operationType);
|
|
73
|
+
if (!handler) {
|
|
74
|
+
console.error(`No handler found for operation type: ${operationType}`);
|
|
75
|
+
return null;
|
|
76
|
+
}
|
|
77
|
+
return handler;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
### 2. Directory Structure
|
|
83
|
+
```
|
|
84
|
+
src/core/state/
|
|
85
|
+
├── handlers/
|
|
86
|
+
│ ├── base/
|
|
87
|
+
│ │ ├── BaseHandler.js
|
|
88
|
+
│ ├── addAdminContract/
|
|
89
|
+
│ │ ├── AddAdminHandler.js
|
|
90
|
+
│ ├── adminRecoveryContract/
|
|
91
|
+
│ │ └── AdminRecoveryHandler.js
|
|
92
|
+
│ ├── addWriterContract/
|
|
93
|
+
│ │ ├── AddWriterHandler.js
|
|
94
|
+
│ ├── addRemoveContract/
|
|
95
|
+
│ │ └── RemoveWriterHandler.js
|
|
96
|
+
│ ├── addIndexercontract/
|
|
97
|
+
│ │ ├── AddIndexerHandler.js
|
|
98
|
+
│ ├── removeIndexercontract/
|
|
99
|
+
│ │ └── RemoveIndexerHandler.js // and other contracts
|
|
100
|
+
│ └── HandlerFactory.js
|
|
101
|
+
├── utils/
|
|
102
|
+
│ ├── balance.js // and other utils
|
|
103
|
+
├── validation/
|
|
104
|
+
│ └── BalanceValidator.js // we can separate implement specific validators which can be used everywhere
|
|
105
|
+
└── State.js
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
### 3. Integration with State Class
|
|
109
|
+
|
|
110
|
+
```javascript
|
|
111
|
+
const HandlerFactory = require('./handlers/HandlerFactory');
|
|
112
|
+
|
|
113
|
+
class State extends ReadyResource {
|
|
114
|
+
constructor() {
|
|
115
|
+
super();
|
|
116
|
+
this.handlerFactory = new HandlerFactory(this);
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
#getApplyOperationHandler(type) {
|
|
120
|
+
return this.handlerFactory.getHandler(type);
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
async #apply(nodes, view, base) {
|
|
124
|
+
const batch = this.#setupHyperbee(base);
|
|
125
|
+
|
|
126
|
+
for (const node of nodes) {
|
|
127
|
+
const operation = node.value;
|
|
128
|
+
const handler = this.#getApplyOperationHandler(operation.type);
|
|
129
|
+
await handler.handle(operation, view, base, node, batch);
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
await batch.flush();
|
|
133
|
+
await batch.clode();
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
}
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
### 4. Handler Implementation Example
|
|
140
|
+
```javascript
|
|
141
|
+
export class AddWriterHandler extends BaseHandler {
|
|
142
|
+
async handle(op, view, base, node, batch) {
|
|
143
|
+
const schemaValidation = await this.#validateRoleAccessOperation(op);
|
|
144
|
+
if (!schemaValidation) { validatorPunishment(); return;}
|
|
145
|
+
|
|
146
|
+
const addressData = await this.#validateAddress(op, node);
|
|
147
|
+
if (!addressData) { validatorPunishment(); return;}
|
|
148
|
+
|
|
149
|
+
const signatureData = await this.#validateSignatures(op, base, batch);
|
|
150
|
+
if (!signatureData) { validatorPunishment(); return;}
|
|
151
|
+
|
|
152
|
+
await this.#addWriter(
|
|
153
|
+
op,
|
|
154
|
+
base,
|
|
155
|
+
node,
|
|
156
|
+
batch,
|
|
157
|
+
...
|
|
158
|
+
);
|
|
159
|
+
}
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
### 5. Common Functionality Modules
|
|
163
|
+
```javascript
|
|
164
|
+
export class BalanceValidator {
|
|
165
|
+
#safeLog;
|
|
166
|
+
|
|
167
|
+
constructor(safeLog) {
|
|
168
|
+
this.#safeLog = safeLog;
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
validateFeePayment(nodeEntry, balance, fee, validatorWk) {
|
|
172
|
+
if (!balance.greaterThanOrEquals(fee)) {
|
|
173
|
+
this.#safeLog("Balance", "Insufficient balance for fee payment", validatorWk);
|
|
174
|
+
return null;
|
|
175
|
+
}
|
|
176
|
+
return {
|
|
177
|
+
newBalance: balance.sub(fee)
|
|
178
|
+
};
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
## Benefits
|
|
184
|
+
|
|
185
|
+
1. **Maintainability**
|
|
186
|
+
- Smaller, focused files
|
|
187
|
+
- Clear separation of concerns
|
|
188
|
+
- Easier to understand and modify individual handlers
|
|
189
|
+
|
|
190
|
+
2. **Testability**
|
|
191
|
+
- Isolated handler testing
|
|
192
|
+
- Mockable dependencies
|
|
193
|
+
|
|
194
|
+
3. **Code Reuse**
|
|
195
|
+
- Shared validation logic
|
|
196
|
+
|
|
197
|
+
## Compatibility Requirements
|
|
198
|
+
|
|
199
|
+
1. **Behavioral Compatibility**
|
|
200
|
+
- Refactored code MUST behave identically to the current implementation
|
|
201
|
+
- All validations and errors MUST be returned at the same points
|
|
202
|
+
- Operation execution order MUST remain unchanged
|
|
203
|
+
- Business logic MUST be identical, only code structure changes
|
|
204
|
+
|
|
205
|
+
2. **State Consistency**
|
|
206
|
+
- DAG in refactored node MUST be byte-by-byte identical with other nodes
|
|
207
|
+
- All state operations MUST produce the same results
|
|
208
|
+
- State replication between nodes MUST work without changes
|
|
209
|
+
- Batch processing MUST maintain the same atomicity
|
|
210
|
+
|
|
211
|
+
3. **Network Compatibility**
|
|
212
|
+
- Nodes with old and new implementation MUST work together in the network
|
|
213
|
+
- Message format and communication MUST remain unchanged
|
|
214
|
+
- No hard fork or protocol changes should be required
|
|
215
|
+
|
|
216
|
+
4. **Validation Points**
|
|
217
|
+
- Byte-by-byte comparison of all state operations
|
|
218
|
+
- Verification of DAG identity after replication
|
|
219
|
+
- Testing node cooperation in testnet
|
|
220
|
+
- Verification of batch processing consistency
|
|
File without changes
|
package/msb.mjs
CHANGED
|
@@ -1,14 +1,45 @@
|
|
|
1
1
|
import {MainSettlementBus} from './src/index.js';
|
|
2
2
|
|
|
3
|
+
const isPear = typeof Pear !== 'undefined';
|
|
4
|
+
const args = isPear ? Pear.config.args : process.argv.slice(2);
|
|
5
|
+
|
|
3
6
|
const opts = {
|
|
4
|
-
stores_directory : '
|
|
7
|
+
stores_directory : 'stores/',
|
|
5
8
|
store_name : typeof process !== "undefined" ? process.argv[2] : Pear.config.args[0],
|
|
6
|
-
bootstrap: '
|
|
7
|
-
channel: '
|
|
9
|
+
bootstrap: '602d5443c19014e36a01254923afb1df56099d559f282761d70370a0da5d1d8a',
|
|
10
|
+
channel: 'TESTNET0002tracnetworkmainsettlementbus',
|
|
11
|
+
enable_role_requester: false,
|
|
12
|
+
enable_auto_transaction_consent: false,
|
|
13
|
+
enable_wallet: true,
|
|
14
|
+
enable_validator_observer: true,
|
|
15
|
+
enable_interactive_mode: true,
|
|
16
|
+
disable_rate_limit: true,
|
|
17
|
+
enable_txlogs: true,
|
|
8
18
|
};
|
|
9
19
|
|
|
10
|
-
const
|
|
20
|
+
const rpc_opts = {
|
|
21
|
+
...opts,
|
|
22
|
+
enable_txlogs: false,
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
const msb = new MainSettlementBus(args.includes('--rpc') ? rpc_opts : opts);
|
|
26
|
+
|
|
27
|
+
msb.ready().then(async () => {
|
|
28
|
+
const runRpc = args.includes('--rpc');
|
|
29
|
+
|
|
30
|
+
if (runRpc) {
|
|
31
|
+
console.log('Starting RPC server...');
|
|
32
|
+
const portIndex = args.indexOf('--port');
|
|
33
|
+
const port = (portIndex !== -1 && args[portIndex + 1]) ? parseInt(args[portIndex + 1], 10) : 5000;
|
|
34
|
+
const hostIndex = args.indexOf('--host');
|
|
35
|
+
const host = (hostIndex !== -1 && args[hostIndex + 1]) ? args[hostIndex + 1] : 'localhost';
|
|
36
|
+
|
|
37
|
+
const {startRpcServer} = await import('./rpc/rpc_server.mjs');
|
|
38
|
+
startRpcServer(msb, host, port);
|
|
39
|
+
} else {
|
|
40
|
+
console.log('RPC server will not be started.');
|
|
41
|
+
}
|
|
11
42
|
|
|
12
|
-
msb.ready().then(() => {
|
|
13
43
|
msb.interactiveMode();
|
|
14
|
-
});
|
|
44
|
+
});
|
|
45
|
+
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "trac-msb",
|
|
3
3
|
"main": "msb.mjs",
|
|
4
|
-
"version": "0.1.
|
|
4
|
+
"version": "0.1.77-msb-r2-dev.1",
|
|
5
5
|
"pear": {
|
|
6
6
|
"name": "trac-msb",
|
|
7
7
|
"type": "terminal"
|
|
@@ -9,32 +9,56 @@
|
|
|
9
9
|
"type": "module",
|
|
10
10
|
"scripts": {
|
|
11
11
|
"dev": "pear run -d .",
|
|
12
|
-
"
|
|
13
|
-
"
|
|
12
|
+
"dev-rpc": "pear run -d . ${npm_config_store} --rpc --port ${npm_config_port}",
|
|
13
|
+
"prod-rpc": "pear run . ${npm_config_store} --rpc --host ${npm_config_host} --port ${npm_config_port}",
|
|
14
|
+
"protobuf": "node scripts/generate-protobufs.js",
|
|
15
|
+
"test:acceptance": "node --experimental-vm-modules node_modules/jest/bin/jest.js --testTimeout=200000 test/acceptance/",
|
|
16
|
+
"test:node": "brittle-node -t 120000 test/all.test.js",
|
|
17
|
+
"test:bare": "brittle-bare -t 120000 test/all.test.js",
|
|
18
|
+
"test:node:cov": "brittle-node -c -t 120000 test/all.test.js",
|
|
19
|
+
"test:bare:cov": "brittle-bare -c -t 120000 test/all.test.js"
|
|
14
20
|
},
|
|
15
21
|
"dependencies": {
|
|
16
|
-
"
|
|
17
|
-
"
|
|
18
|
-
"corestore": "^7.4.2",
|
|
22
|
+
"@tracsystems/blake3": "^0.0.13",
|
|
23
|
+
"autobase": "7.16.1",
|
|
19
24
|
"b4a": "1.6.7",
|
|
25
|
+
"bare-crypto": "^1.11.2",
|
|
26
|
+
"bare-fs": "^4.1.6",
|
|
27
|
+
"bare-http1": "^4.0.4",
|
|
20
28
|
"bare-readline": "1.0.7",
|
|
21
29
|
"bare-tty": "5.0.2",
|
|
30
|
+
"bech32": "^2.0.0",
|
|
31
|
+
"brittle": "^3.17.1",
|
|
22
32
|
"compact-encoding": "^2.16.0",
|
|
33
|
+
"corestore": "^7.4.2",
|
|
34
|
+
"crypto": "npm:bare-node-crypto",
|
|
23
35
|
"fastest-validator": "1.19.0",
|
|
36
|
+
"http": "npm:bare-node-http",
|
|
24
37
|
"hyperbee": "^2.24.2",
|
|
38
|
+
"hypercore": "^11.6.3",
|
|
25
39
|
"hypercore-crypto": "^3.4.0",
|
|
26
40
|
"hyperdht": "^6.20.5",
|
|
27
41
|
"hyperswarm": "^4.11.5",
|
|
42
|
+
"protocol-buffers-encodings": "^1.2.0",
|
|
28
43
|
"protomux": "^3.10.1",
|
|
29
44
|
"protomux-wakeup": "2.4.0",
|
|
30
45
|
"readline": "npm:bare-node-readline",
|
|
31
46
|
"ready-resource": "1.1.2",
|
|
32
|
-
"trac-wallet": "0.0.43",
|
|
47
|
+
"trac-wallet": "0.0.43-msb-r2.4",
|
|
33
48
|
"tty": "npm:bare-node-tty"
|
|
34
49
|
},
|
|
50
|
+
"devDependencies": {
|
|
51
|
+
"bare-os": "^3.6.1",
|
|
52
|
+
"bip39-mnemonic": "^2.4.0",
|
|
53
|
+
"esmock": "^2.7.2",
|
|
54
|
+
"jest": "^30.1.3",
|
|
55
|
+
"protocol-buffers": "^4.2.0",
|
|
56
|
+
"sinon": "^21.0.0",
|
|
57
|
+
"supertest": "^7.1.4",
|
|
58
|
+
"trac-crypto-api": "^0.0.10"
|
|
59
|
+
},
|
|
35
60
|
"publishConfig": {
|
|
36
61
|
"registry": "https://registry.npmjs.org",
|
|
37
|
-
"access": "public"
|
|
38
|
-
"brittle": "^3.16.2"
|
|
62
|
+
"access": "public"
|
|
39
63
|
}
|
|
40
64
|
}
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
syntax = "proto3";
|
|
2
|
+
|
|
3
|
+
package apply.operations;
|
|
4
|
+
|
|
5
|
+
//DO NOT CHANGE THE ORDER AFTER RELEASE - ONLY APPEND NEW ONES
|
|
6
|
+
enum OperationType {
|
|
7
|
+
UNKNOWN = 0;
|
|
8
|
+
ADD_ADMIN = 1; // complete
|
|
9
|
+
DISABLE_INITIALIZATION = 2; // complete
|
|
10
|
+
BALANCE_INITIALIZATION = 3; // complete
|
|
11
|
+
APPEND_WHITELIST = 4; // complete
|
|
12
|
+
ADD_WRITER = 5; // partial
|
|
13
|
+
REMOVE_WRITER = 6; // partial
|
|
14
|
+
ADMIN_RECOVERY = 7; // partial
|
|
15
|
+
ADD_INDEXER = 8; // complete
|
|
16
|
+
REMOVE_INDEXER = 9; // complete
|
|
17
|
+
BAN_VALIDATOR = 10; // complete
|
|
18
|
+
BOOTSTRAP_DEPLOYMENT = 11; // partial
|
|
19
|
+
TX = 12; // partial
|
|
20
|
+
TRANSFER = 13; // partial
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
// add admin operation, disable_initialization (complete by default)
|
|
24
|
+
message CoreAdminOperation {
|
|
25
|
+
bytes tx = 1; // Transaction hash (unique identifier for the transaction)
|
|
26
|
+
bytes txv = 2; // Transaction expiration
|
|
27
|
+
bytes iw = 3; // incoming writer key (admin)
|
|
28
|
+
bytes in = 4; // Nonce of the invoker (admin)
|
|
29
|
+
bytes is = 5; // Signature of the invoker (admin)
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
// append_whitelist, add_indexer, remove_indexer, ban_writer (complete by default)
|
|
33
|
+
message AdminControlOperation {
|
|
34
|
+
bytes tx = 1; // Transaction hash (unique identifier for the transaction)
|
|
35
|
+
bytes txv = 2; // Transaction expiration
|
|
36
|
+
bytes in = 3; // Nonce of the invoker (admin)
|
|
37
|
+
bytes ia = 4; // selected address to specific operation.
|
|
38
|
+
bytes is = 5; // Signature of the invoker (admin)
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
// balance_initialization (complete by default)
|
|
42
|
+
message BalanceInitializationOperation {
|
|
43
|
+
bytes tx = 1; // Transaction hash (unique identifier for the transaction)
|
|
44
|
+
bytes txv = 2; // Transaction expiration
|
|
45
|
+
bytes in = 3; // Nonce of the contract invoker (admin)
|
|
46
|
+
bytes ia = 4; // selected address to specific operation.
|
|
47
|
+
bytes am = 5; // Initial balance to be set for the address
|
|
48
|
+
bytes is = 6; // Signature of the contract invoker (admin)
|
|
49
|
+
}
|
|
50
|
+
// token_transfer (partial - need to be signed by another writer to be complete)
|
|
51
|
+
message TransferOperation {
|
|
52
|
+
bytes tx = 1; // Transaction hash (unique identifier for the transaction)
|
|
53
|
+
bytes txv = 2; // Transaction expiration
|
|
54
|
+
bytes in = 3; // Nonce of the invoker (any account)
|
|
55
|
+
bytes to = 4; // Address of the recipient (any account)
|
|
56
|
+
bytes am = 5; // Amount of tokens to transfer
|
|
57
|
+
bytes is = 6; // Signature of the invoker (any account)
|
|
58
|
+
bytes va = 7; // Validator's address (optional)
|
|
59
|
+
bytes vn = 8; // Validator's nonce (optional)
|
|
60
|
+
bytes vs = 9; // Validator's signature (optional)
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
// add_writer, remove_writer, admin_recovery (partial - need to be signed by another writer to be complete)
|
|
64
|
+
message RoleAccessOperation {
|
|
65
|
+
bytes tx = 1; // Transaction hash (unique identifier for the transaction)
|
|
66
|
+
bytes txv = 2; // Transaction expiration
|
|
67
|
+
bytes iw = 3; // Writing key of the invoker (whitelisted node, admin to be recovered, Trac Network)
|
|
68
|
+
bytes in = 4; // Nonce of the invoker (whitelisted node, admin to be recovered, Trac Network)
|
|
69
|
+
bytes is = 5; // Signature of the invoker (whitelisted node, admin to be recovered)
|
|
70
|
+
bytes va = 6; // Validator's address (optional)
|
|
71
|
+
bytes vn = 7; // Validator's nonce (optional)
|
|
72
|
+
bytes vs = 8; // Validator's signature (optional)
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
// transaction - (partial - need to be signed by another writer to be complete)
|
|
76
|
+
message TxOperation {
|
|
77
|
+
bytes tx = 1; // Transaction hash (unique identifier for the transaction)
|
|
78
|
+
bytes txv = 2; // Transaction expiration
|
|
79
|
+
bytes iw = 3; // Writing key of the requesting node (external subnetwork)
|
|
80
|
+
bytes in = 4; // Nonce of the requesting node
|
|
81
|
+
bytes ch = 5; // Content hash (hash of the transaction's data)
|
|
82
|
+
bytes is = 6; // Requester's signature
|
|
83
|
+
bytes bs = 7; // External bootstrap contract
|
|
84
|
+
bytes mbs = 8; // MSB bootstrap key
|
|
85
|
+
bytes va = 9; // Validator's address (optional)
|
|
86
|
+
bytes vn = 10; // Validator's nonce (optional)
|
|
87
|
+
bytes vs = 11; // Validator's signature (optional)
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
// bootstrap deployment - (partial - need to be signed by another writer to be complete)
|
|
91
|
+
message BootstrapDeploymentOperation {
|
|
92
|
+
bytes tx = 1; // Transaction hash (unique identifier for the transaction)
|
|
93
|
+
bytes txv = 2; // Transaction expiration
|
|
94
|
+
bytes bs = 3; // Bootstrap contract address
|
|
95
|
+
bytes ic = 4; // Channel on which the contract will operate
|
|
96
|
+
bytes in = 5; // Nonce of the contract invoker
|
|
97
|
+
bytes is = 6; // Signature of the contract invoker
|
|
98
|
+
bytes va = 7; // Validator's address (optional)
|
|
99
|
+
bytes vn = 8; // Validator's nonce (optional)
|
|
100
|
+
bytes vs = 9; // Validator's signature (optional)
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
// Main structure for the operations where messages are
|
|
104
|
+
message Operation {
|
|
105
|
+
OperationType type = 1;
|
|
106
|
+
bytes address = 2; // address of the invoker
|
|
107
|
+
|
|
108
|
+
oneof value {
|
|
109
|
+
CoreAdminOperation cao = 3;
|
|
110
|
+
AdminControlOperation aco = 4;
|
|
111
|
+
BalanceInitializationOperation bio = 5;
|
|
112
|
+
TransferOperation tro = 6;
|
|
113
|
+
RoleAccessOperation rao = 7;
|
|
114
|
+
BootstrapDeploymentOperation bdo = 8;
|
|
115
|
+
TxOperation txo = 9;
|
|
116
|
+
}
|
|
117
|
+
}
|
package/rpc/cors.mjs
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export function applyCors(req, res) {
|
|
2
|
+
// Set CORS headers
|
|
3
|
+
res.setHeader('Access-Control-Allow-Origin', '*'); // Allow all origins, or specify a domain
|
|
4
|
+
res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS');
|
|
5
|
+
res.setHeader('Access-Control-Allow-Headers', 'Content-Type');
|
|
6
|
+
|
|
7
|
+
// Handle preflight OPTIONS request
|
|
8
|
+
if (req.method === 'OPTIONS') {
|
|
9
|
+
res.writeHead(204);
|
|
10
|
+
res.end();
|
|
11
|
+
return true; // Return true to indicate the request was handled
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
return false; // Return false to indicate the request should be handled by the main router
|
|
15
|
+
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
// rpc_server.mjs
|
|
2
|
+
import http from 'http'
|
|
3
|
+
import { applyCors } from './cors.mjs';
|
|
4
|
+
import { routes } from './router.mjs'; // Import the new routes array
|
|
5
|
+
|
|
6
|
+
export const createServer = (msbInstance) => {
|
|
7
|
+
const server = http.createServer({}, async (req, res) => {
|
|
8
|
+
if (applyCors(req, res)) return;
|
|
9
|
+
|
|
10
|
+
const respond = (code, paylaod) => {
|
|
11
|
+
res.writeHead(code, { 'Content-Type': 'application/json' });
|
|
12
|
+
res.end(JSON.stringify(paylaod));
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
// Find the matching route
|
|
16
|
+
let foundRoute = false;
|
|
17
|
+
for (const route of routes) {
|
|
18
|
+
// Simple path matching
|
|
19
|
+
if (req.method === route.method && req.url.startsWith(route.path)) {
|
|
20
|
+
foundRoute = true;
|
|
21
|
+
try {
|
|
22
|
+
await route.handler({ req, res, respond, msbInstance });
|
|
23
|
+
} catch (error) {
|
|
24
|
+
console.error(`Error on ${route.path}:`, error);
|
|
25
|
+
res.writeHead(500, { 'Content-Type': 'application/json' });
|
|
26
|
+
res.end(JSON.stringify({ error: 'An error occurred processing the request.' }));
|
|
27
|
+
}
|
|
28
|
+
break;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
if (!foundRoute) {
|
|
33
|
+
res.writeHead(404, { 'Content-Type': 'text/plain' });
|
|
34
|
+
res.end('Not Found');
|
|
35
|
+
}
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
return server
|
|
39
|
+
}
|