tigerbeetle-node 0.6.0 → 0.9.0

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 (51) hide show
  1. package/README.md +102 -83
  2. package/dist/benchmark.js +102 -100
  3. package/dist/benchmark.js.map +1 -1
  4. package/dist/index.d.ts +82 -82
  5. package/dist/index.js +74 -93
  6. package/dist/index.js.map +1 -1
  7. package/dist/test.js +135 -112
  8. package/dist/test.js.map +1 -1
  9. package/package.json +13 -14
  10. package/scripts/download_node_headers.sh +3 -1
  11. package/src/benchmark.ts +114 -118
  12. package/src/index.ts +102 -111
  13. package/src/node.zig +53 -51
  14. package/src/test.ts +146 -125
  15. package/src/tigerbeetle/scripts/benchmark.bat +46 -46
  16. package/src/tigerbeetle/scripts/benchmark.sh +5 -0
  17. package/src/tigerbeetle/scripts/install_zig.bat +109 -109
  18. package/src/tigerbeetle/scripts/install_zig.sh +7 -3
  19. package/src/tigerbeetle/scripts/vopr.bat +47 -47
  20. package/src/tigerbeetle/src/benchmark.zig +63 -96
  21. package/src/tigerbeetle/src/config.zig +23 -19
  22. package/src/tigerbeetle/src/demo.zig +2 -15
  23. package/src/tigerbeetle/src/demo_01_create_accounts.zig +10 -10
  24. package/src/tigerbeetle/src/demo_03_create_transfers.zig +5 -3
  25. package/src/tigerbeetle/src/{demo_04_create_transfers_two_phase_commit.zig → demo_04_create_pending_transfers.zig} +18 -12
  26. package/src/tigerbeetle/src/demo_05_post_pending_transfers.zig +37 -0
  27. package/src/tigerbeetle/src/demo_06_void_pending_transfers.zig +24 -0
  28. package/src/tigerbeetle/src/demo_07_lookup_transfers.zig +1 -1
  29. package/src/tigerbeetle/src/io/linux.zig +4 -4
  30. package/src/tigerbeetle/src/main.zig +19 -3
  31. package/src/tigerbeetle/src/message_pool.zig +5 -2
  32. package/src/tigerbeetle/src/ring_buffer.zig +48 -3
  33. package/src/tigerbeetle/src/simulator.zig +104 -8
  34. package/src/tigerbeetle/src/state_machine.zig +1813 -816
  35. package/src/tigerbeetle/src/test/cluster.zig +165 -32
  36. package/src/tigerbeetle/src/test/packet_simulator.zig +14 -1
  37. package/src/tigerbeetle/src/test/state_checker.zig +3 -1
  38. package/src/tigerbeetle/src/test/state_machine.zig +8 -7
  39. package/src/tigerbeetle/src/test/storage.zig +99 -40
  40. package/src/tigerbeetle/src/tigerbeetle.zig +103 -98
  41. package/src/tigerbeetle/src/vsr/journal.zig +1387 -459
  42. package/src/tigerbeetle/src/vsr/replica.zig +1204 -417
  43. package/src/tigerbeetle/src/vsr.zig +203 -49
  44. package/src/translate.zig +10 -0
  45. package/.yarn/releases/yarn-berry.cjs +0 -55
  46. package/.yarnrc.yml +0 -1
  47. package/scripts/postinstall.sh +0 -6
  48. package/src/tigerbeetle/src/demo_05_accept_transfers.zig +0 -23
  49. package/src/tigerbeetle/src/demo_06_reject_transfers.zig +0 -17
  50. package/src/tigerbeetle/src/format_test.zig +0 -69
  51. package/yarn.lock +0 -42
package/README.md CHANGED
@@ -2,46 +2,32 @@
2
2
  [TigerBeetle](https://github.com/coilhq/tigerbeetle) client for Node.js.
3
3
 
4
4
  ## Installation
5
- The following steps will install the `tigerbeetle-node` module to your current working directory.
6
5
 
7
- ### Prerequisites
6
+ Install the `tigerbeetle-node` module to your current working directory:
8
7
 
9
- * NodeJS >= `14.0.0`. _(If the correct version is not installed, an installation error will occur)_
10
-
11
- > Your operating system should be Linux (kernel >= v5.6) or macOS. Windows support is not yet available but is in the works.
12
-
13
- ### YARN Package Manager
14
-
15
- ```sh
16
- # Run the following from this directory
17
- yarn add
18
- ```
19
- or
20
-
21
- ### NPM Package Manager
22
- ```sh
8
+ ```shell
23
9
  npm install tigerbeetle-node
24
10
  ```
25
11
 
26
- **Development**
12
+ ### Prerequisites
27
13
 
28
- Follow these steps to get up and running when cloning the repo:
14
+ * NodeJS >= `14.0.0`. _(If the correct version is not installed, an installation error will occur)_
29
15
 
30
- ```sh
31
- git clone --recurse-submodules https://github.com/coilhq/tigerbeetle-node.git
32
- yarn
33
- ```
16
+ > Your operating system should be Linux (kernel >= v5.6) or macOS.
17
+ > Windows support is not yet available.
34
18
 
35
19
  ## Usage
20
+
36
21
  A client needs to be configured with a `cluster_id` and `replica_addresses`.
37
22
  This instantiates the client where memory is allocated to internally buffer events to be sent.
38
23
  For the moment, only one client can be instantiated globally per process.
39
24
  Future releases will allow multiple client instantiations.
25
+
40
26
  ```js
41
27
  import { createClient } from 'tigerbeetle-node'
42
28
 
43
29
  const client = createClient({
44
- cluster_id: 1,
30
+ cluster_id: 0,
45
31
  replica_addresses: ['3001', '3002', '3003']
46
32
  })
47
33
  ```
@@ -54,15 +40,15 @@ This is reflected in the below function interfaces where each one takes in an ar
54
40
  ```js
55
41
  const account = {
56
42
  id: 137n, // u128
57
- user_data: 0n, // u128, opaque third-party identifier to link this account (many-to-one) to an external entity:
43
+ user_data: 0n, // u128, opaque third-party identifier to link this account to an external entity:
58
44
  reserved: Buffer.alloc(48, 0), // [48]u8
59
- unit: 1, // u16, unit of value
45
+ ledger: 1, // u32, ledger value
60
46
  code: 718, // u16, a chart of accounts code describing the type of account (e.g. clearing, settlement)
61
- flags: 0, // u32
62
- debits_reserved: 0n, // u64
63
- debits_accepted: 0n, // u64
64
- credits_reserved: 0n, // u64
65
- credits_accepted: 0n, // u64
47
+ flags: 0, // u16
48
+ debits_pending: 0n, // u64
49
+ debits_posted: 0n, // u64
50
+ credits_pending: 0n, // u64
51
+ credits_posted: 0n, // u64
66
52
  timestamp: 0n, // u64, Reserved: This will be set by the server.
67
53
  }
68
54
 
@@ -87,7 +73,7 @@ The `flags` on an account provide a way for you to enforce policies by toggling
87
73
  |----------|----------------------------------|-----------------------------------------|
88
74
  | `linked` | `debits_must_not_exceed_credits` | `credits_must_not_exceed_debits` |
89
75
 
90
- The creation of an account can be linked to the successful creation of another by setting the `linked` flag (see [linked events](#linked-events)). By setting `debits_must_not_exceed_credits`, then any transfer such that `debits_accepted + debits_reserved + amount > credit_accepted` will fail. Similarly for `credits_must_not_exceed_debits`.
76
+ The creation of an account can be linked to the successful creation of another by setting the `linked` flag (see [linked events](#linked-events)). By setting `debits_must_not_exceed_credits`, then any transfer such that `debits_posted + debits_pending + amount > credits_posted` will fail. Similarly for `credits_must_not_exceed_debits`.
91
77
  ```js
92
78
  enum CreateAccountFlags {
93
79
  linked = (1 << 0),
@@ -99,7 +85,7 @@ The creation of an account can be linked to the successful creation of another b
99
85
  flags |= CreateAccountFlags.debits_must_not_exceed_credits
100
86
  ```
101
87
 
102
- ### Account lookup
88
+ ### Account Lookup
103
89
 
104
90
  The `id` of the account is used for lookups. Only matched accounts are returned.
105
91
  ```js
@@ -111,80 +97,78 @@ The `id` of the account is used for lookups. Only matched accounts are returned.
111
97
  * id: 137n,
112
98
  * user_data: 0n,
113
99
  * reserved: Buffer,
114
- * unit: 1,
100
+ * ledger: 1,
115
101
  * code: 718,
116
102
  * flags: 0,
117
- * debits_reserved: 0n,
118
- * debits_accepted: 0n,
119
- * credits_reserved: 0n,
120
- * credits_accepted: 0n,
103
+ * debits_pending: 0n,
104
+ * debits_posted: 0n,
105
+ * credits_pending: 0n,
106
+ * credits_posted: 0n,
121
107
  * timestamp: 1623062009212508993n,
122
108
  * }]
123
109
  */
124
110
  ```
125
111
 
126
- ### Creating a transfer
112
+ ### Creating a Transfer
127
113
 
128
114
  This creates a journal entry between two accounts.
129
115
  ```js
130
116
  const transfer = {
131
117
  id: 1n, // u128
118
+ // Double-entry accounting:
132
119
  debit_account_id: 1n, // u128
133
120
  credit_account_id: 2n, // u128
134
- user_data: 0n, // u128, opaque third-party identifier to link this transfer (many-to-one) to an external entity
135
- reserved: Buffer.alloc(32, 0), // two-phase condition can go in here
136
- timeout: 0n, // u64, in nano-seconds.
137
- code: 1, // u32, a chart of accounts code describing the reason for the transfer (e.g. deposit, settlement)
138
- flags: 0, // u32
121
+ // Opaque third-party identifier to link this transfer to an external entity:
122
+ user_data: 0n, // u128
123
+ reserved: 0n, // u128
124
+ // Timeout applicable for a pending/2-phase transfer:
125
+ timeout: 0n, // u64, in nano-seconds.
126
+ // Collection of accounts usually grouped by the currency:
127
+ // You can't transfer money between accounts with different ledgers:
128
+ ledger: 720, // u32, ledger for transfer (e.g. currency).
129
+ // Chart of accounts code describing the reason for the transfer:
130
+ code: 1, // u16, (e.g. deposit, settlement)
131
+ flags: 0, // u16
139
132
  amount: 10n, // u64
140
133
  timestamp: 0n, //u64, Reserved: This will be set by the server.
141
134
  }
142
-
143
135
  const errors = await client.createTransfers([transfer])
144
136
  ```
145
- Two-phase transfers are supported natively by toggling the appropriate flag. TigerBeetle will then adjust the `credits_reserved` and `debits_reserved` fields of the appropriate accounts. A corresponding commit transfer then needs to be sent to accept or reject the transfer.
146
- | bit 0 | bit 1 | bit 2 |
147
- |----------|--------------------|------------------|
148
- | `linked` | `posting` | `condition` |
137
+ Two-phase transfers are supported natively by toggling the appropriate flag. TigerBeetle will then adjust the `credits_pending` and `debits_pending` fields of the appropriate accounts. A corresponding commit transfer then needs to be sent to accept or reject the transfer.
149
138
 
150
- The `condition` flag signals to TigerBeetle that a 256-bit cryptographic condition will be supplied in the `reserved` field. This will be validated against a supplied pre-image when the transfer is committed. Transfers within a batch may also be linked (see [linked events](#linked-events)).
139
+ Transfers within a batch may also be linked (see [linked events](#linked-events)).
151
140
  ```js
152
- enum CreateTransferFlags {
153
- linked = (1 << 0>>),
154
- two_phase_commit = (1 << 1),
155
- condition = (1 << 2)
141
+ enum TransferFlags {
142
+ linked = (1 << 0),
143
+ pending = (1 << 1),
144
+ post_pending_transfer = (1 << 2),
145
+ void_pending_transfer = (1 << 3)
156
146
  }
157
-
158
- // two-phase transfer
147
+
148
+ // Two-phase transfer (pending):
159
149
  let flags = 0n
160
- flags |= TransferFlags.two_phase_commit
150
+ flags |= TransferFlags.pending
161
151
 
162
- // two-phase transfer with condition supplied in `reserved`
152
+ // Linked two-phase transfer (pending):
163
153
  let flags = 0n
164
- flags |= TransferFlags.two_phase_commit
165
- flags |= TransferFlags.condition
154
+ flags |= TransferFlags.linked
155
+ flags |= TransferFlags.pending
166
156
  ```
167
157
 
168
- ### Committing a transfer
169
-
170
- This is used to commit a two-phase transfer.
171
- | bit 0 | bit 1 | bit 2 |
172
- |----------|----------|------------|
173
- | `linked` | `reject` | `preimage` |
158
+ ### Post a Pending Transfer (2-Phase)
174
159
 
175
- By default (`flags = 0`), it will accept the transfer. TigerBeetle will atomically rollback the changes to `debits_reserved` and `credits_reserved` of the appropriate accounts and apply them to the `debits_accepted` and `credits_accepted` balances. If the `preimage` bit is set then TigerBeetle will look for it in the `reserved` field and validate it against the `condition` from the associated transfer. If this validation fails, or `reject` is set, then the changes to the `reserved` balances are atomically rolled back.
160
+ With `flags = post_pending_transfer`, TigerBeetle will accept the transfer. TigerBeetle will atomically rollback the changes to `debits_pending` and `credits_pending` of the appropriate accounts and apply them to the `debits_posted` and `credits_posted` balances.
176
161
  ```js
177
- const commit = {
178
- id: 1n, // u128, must correspond to the transfer id
179
- reserved: Buffer.alloc(32, 0), // [32]u8
180
- code: 1, // u32, accounting system code to identify type of transfer
181
- flags: 0, // u32
162
+ const post = {
163
+ id: 2n, // u128, must correspond to the transfer id
164
+ pending_id: 1n, // u128, id of the pending transfer
165
+ flags: TransferFlags.post_pending_transfer, // to void, use [void_pending_transfer]
182
166
  timestamp: 0n, // u64, Reserved: This will be set by the server.
183
167
  }
184
- const errors = await client.commitTransfers([commit])
168
+ const errors = await client.createTransfers([post])
185
169
  ```
186
170
 
187
- ### Linked events
171
+ ### Linked Events
188
172
 
189
173
  When the `linked` flag is specified for the `createAccount`, `createTransfer`, `commitTransfer` event, it links an event with the next event in the batch, to create a chain of events, of arbitrary length, which all succeed or fail together. The tail of a chain is denoted by the first event without this flag. The last event in a batch may therefore never have the `linked` flag set as this would leave a chain open-ended. Multiple chains or individual events may coexist within a batch to succeed or fail independently. Events within a chain are executed within order, or are rolled back on error, so that the effect of each event in the chain is visible to the next, and so that the chain is either visible or invisible as a unit to subsequent events after the chain. The event that was the first to break the chain will have a unique error result. Other events in the chain will have their error result set to `linked_event_failed`.
190
174
 
@@ -193,10 +177,10 @@ let batch = []
193
177
  let linkedFlag = 0
194
178
  linkedFlag |= CreateTransferFlags.linked
195
179
 
196
- // An individual transfer (successful)
180
+ // An individual transfer (successful):
197
181
  batch.push({ id: 1n, ... })
198
182
 
199
- // A chain of 4 transfers (the last transfer in the chain closes the chain with linked=false)
183
+ // A chain of 4 transfers (the last transfer in the chain closes the chain with linked=false):
200
184
  batch.push({ id: 2n, ..., flags: linkedFlag }) // Commit/rollback.
201
185
  batch.push({ id: 3n, ..., flags: linkedFlag }) // Commit/rollback.
202
186
  batch.push({ id: 2n, ..., flags: linkedFlag }) // Fail with exists
@@ -206,11 +190,11 @@ batch.push({ id: 4n, ..., flags: 0 }) // Fail without committing.
206
190
  // This should not see any effect from the failed chain above.
207
191
  batch.push({ id: 2n, ..., flags: 0 })
208
192
 
209
- // A chain of 2 transfers (the first transfer fails the chain)
193
+ // A chain of 2 transfers (the first transfer fails the chain):
210
194
  batch.push({ id: 2n, ..., flags: linkedFlag })
211
195
  batch.push({ id: 3n, ..., flags: 0 })
212
196
 
213
- // A chain of 2 transfers (successful)
197
+ // A chain of 2 transfers (successful):
214
198
  batch.push({ id: 3n, ..., flags: linkedFlag })
215
199
  batch.push({ id: 4n, ..., flags: 0 })
216
200
 
@@ -218,13 +202,48 @@ const errors = await client.createTransfers(batch)
218
202
 
219
203
  /**
220
204
  * [
221
- * { index: 1, error: 1 }, // linked_event_failed
222
- * { index: 2, error: 1 }, // linked_event_failed
223
- * { index: 3, error: 2 }, // exists
224
- * { index: 4, error: 1 }, // linked_event_failed
205
+ * { index: 1, error: 1 }, // linked_event_failed
206
+ * { index: 2, error: 1 }, // linked_event_failed
207
+ * { index: 3, error: 25 }, // exists
208
+ * { index: 4, error: 1 }, // linked_event_failed
225
209
  *
226
- * { index: 6, error: 7 }, // exists_with_different_flags
227
- * { index: 7, error: 1 }, // linked_event_failed
210
+ * { index: 6, error: 17 }, // exists_with_different_flags
211
+ * { index: 7, error: 1 }, // linked_event_failed
228
212
  * ]
229
213
  */
230
214
  ```
215
+
216
+ ### Development
217
+
218
+ To get up and running when cloning the repo:
219
+
220
+ ```shell
221
+ git clone --recurse-submodules https://github.com/coilhq/tigerbeetle-node.git
222
+ cd tigerbeetle-node/
223
+ npm install --include dev # This will automatically install and build everything you need.
224
+ ```
225
+
226
+ #### Rebuild
227
+
228
+ To rebuild the TypeScript distribution, and to rebuild the native Node library, again after changes:
229
+
230
+ ```shell
231
+ npm run build
232
+ ```
233
+
234
+ *If you ever run `npm run clean` then you will need to `npm install --include dev` to reinstall
235
+ TypeScript within `node_modules`, as TypeScript is required by `npm run prepack` when publishing.*
236
+
237
+ #### Benchmark
238
+
239
+ ```shell
240
+ npm run benchmark
241
+ ```
242
+
243
+ #### Test
244
+
245
+ ```shell
246
+ ./tigerbeetle init --cluster=1 --replica=0 --directory=.
247
+ ./tigerbeetle start --cluster=1 --replica=0 --directory=. --addresses=3001
248
+ npm run test
249
+ ```
package/dist/benchmark.js CHANGED
@@ -5,46 +5,44 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  const assert_1 = __importDefault(require("assert"));
7
7
  const _1 = require(".");
8
- const MAX_TRANSFERS = 1000000;
9
- const MAX_REQUEST_BATCH_SIZE = 10000;
10
- const IS_TWO_PHASE_COMMIT = false;
8
+ const MAX_TRANSFERS = 51200;
9
+ const MAX_REQUEST_BATCH_SIZE = 5120;
10
+ const IS_TWO_PHASE_TRANSFER = false;
11
11
  const IS_RAW_REQUEST = false;
12
- const PREVIOUS_RAW_REQUEST_RESULT = IS_TWO_PHASE_COMMIT ? 300000 : 620000;
13
- const PREVIOUS_RESULT = IS_TWO_PHASE_COMMIT ? 150000 : 310000;
12
+ const PREVIOUS_RAW_REQUEST_RESULT = IS_TWO_PHASE_TRANSFER ? 300000 : 620000;
13
+ const PREVIOUS_RESULT = IS_TWO_PHASE_TRANSFER ? 150000 : 310000;
14
14
  const PREVIOUS_BENCHMARK = IS_RAW_REQUEST ? PREVIOUS_RAW_REQUEST_RESULT : PREVIOUS_RESULT;
15
15
  const TOLERANCE = 10;
16
- const client = _1.createClient({
17
- cluster_id: 1,
16
+ const client = (0, _1.createClient)({
17
+ cluster_id: 0,
18
18
  replica_addresses: ['3001']
19
19
  });
20
20
  const TRANSFER_SIZE = 128;
21
- const COMMIT_SIZE = 64;
22
21
  const Zeroed48Bytes = Buffer.alloc(48, 0);
23
- const Zeroed32Bytes = Buffer.alloc(32, 0);
24
22
  const accountA = {
25
23
  id: 137n,
26
24
  user_data: 0n,
27
25
  reserved: Zeroed48Bytes,
28
- code: 0,
26
+ ledger: 1,
27
+ code: 1,
29
28
  flags: 0,
30
- unit: 1,
31
- debits_accepted: 0n,
32
- debits_reserved: 0n,
33
- credits_accepted: 0n,
34
- credits_reserved: 0n,
29
+ debits_pending: 0n,
30
+ debits_posted: 0n,
31
+ credits_pending: 0n,
32
+ credits_posted: 0n,
35
33
  timestamp: 0n,
36
34
  };
37
35
  const accountB = {
38
36
  id: 138n,
39
37
  user_data: 0n,
40
38
  reserved: Zeroed48Bytes,
41
- code: 0,
39
+ ledger: 1,
40
+ code: 1,
42
41
  flags: 0,
43
- unit: 1,
44
- debits_accepted: 0n,
45
- debits_reserved: 0n,
46
- credits_accepted: 0n,
47
- credits_reserved: 0n,
42
+ debits_pending: 0n,
43
+ debits_posted: 0n,
44
+ credits_pending: 0n,
45
+ credits_posted: 0n,
48
46
  timestamp: 0n,
49
47
  };
50
48
  const rawCreateTransfers = async (batch) => {
@@ -63,46 +61,30 @@ const rawCreateTransfers = async (batch) => {
63
61
  }
64
62
  });
65
63
  };
66
- const rawCommitTransfers = async (batch) => {
67
- return new Promise((resolve, reject) => {
68
- const callback = (error, results) => {
69
- if (error) {
70
- reject(error);
71
- }
72
- resolve(results);
73
- };
74
- try {
75
- client.rawRequest(_1.Operation.COMMIT_TRANSFER, batch, callback);
76
- }
77
- catch (error) {
78
- reject(error);
79
- }
80
- });
81
- };
82
64
  const encodeTransfer = (transfer, offset, output) => {
83
- assert_1.default(offset + TRANSFER_SIZE <= output.length);
65
+ (0, assert_1.default)(BigInt((offset + TRANSFER_SIZE)) <= BigInt(output.length), `Transfer ${transfer} exceeds buffer of ${output}!`);
84
66
  output.writeBigUInt64LE(transfer.id, offset);
85
67
  output.writeBigUInt64LE(transfer.debit_account_id, offset + 16);
86
68
  output.writeBigUInt64LE(transfer.credit_account_id, offset + 32);
69
+ output.writeBigUInt64LE(transfer.user_data, offset + 48);
70
+ output.writeBigUInt64LE(transfer.reserved, offset + 64);
71
+ output.writeBigUInt64LE(transfer.pending_id, offset + 80);
87
72
  output.writeBigUInt64LE(transfer.timeout, offset + 96);
88
- output.writeUInt32LE(transfer.code, offset + 104);
89
- output.writeUInt32LE(transfer.flags, offset + 108);
73
+ output.writeUInt32LE(transfer.ledger, offset + 104);
74
+ output.writeUInt32LE(transfer.code, offset + 108);
75
+ output.writeUInt32LE(transfer.flags, offset + 110);
90
76
  output.writeBigUInt64LE(transfer.amount, offset + 112);
91
77
  output.writeBigUInt64LE(transfer.timestamp, offset + 120);
92
78
  };
93
- const encodeCommit = (commit, offset, output) => {
94
- assert_1.default(offset + COMMIT_SIZE <= output.length);
95
- output.writeBigUInt64LE(commit.id, offset);
96
- };
97
- const runBenchmarkRawReqeust = async () => {
98
- assert_1.default(MAX_TRANSFERS % MAX_REQUEST_BATCH_SIZE === 0, "The raw request benchmark requires MAX_TRANSFERS to be a multiple of MAX_REQUEST_BATCH_SIZE");
99
- console.log(`pre-allocating ${MAX_TRANSFERS} transfers and commits...`);
79
+ const runBenchmarkRawRequest = async () => {
80
+ (0, assert_1.default)(MAX_TRANSFERS % MAX_REQUEST_BATCH_SIZE === 0, "The raw request benchmark requires MAX_TRANSFERS to be a multiple of MAX_REQUEST_BATCH_SIZE");
81
+ console.log(`pre-allocating ${MAX_TRANSFERS} transfers and posts...`);
100
82
  const transfers = [];
101
- const commits = [];
83
+ const posts = [];
102
84
  let count = 0;
103
85
  while (count < MAX_TRANSFERS) {
104
86
  const transferBatch = Buffer.alloc(MAX_REQUEST_BATCH_SIZE * TRANSFER_SIZE, 0);
105
- const commitBatch = Buffer.alloc(MAX_REQUEST_BATCH_SIZE * COMMIT_SIZE, 0);
87
+ const postTransferBatch = Buffer.alloc(MAX_REQUEST_BATCH_SIZE * TRANSFER_SIZE, 0);
106
88
  for (let i = 0; i < MAX_REQUEST_BATCH_SIZE; i++) {
107
89
  if (count === MAX_TRANSFERS)
108
90
  break;
@@ -111,45 +93,56 @@ const runBenchmarkRawReqeust = async () => {
111
93
  id: BigInt(count),
112
94
  debit_account_id: accountA.id,
113
95
  credit_account_id: accountB.id,
114
- code: 0,
115
- reserved: Zeroed32Bytes,
116
96
  user_data: 0n,
117
- flags: IS_TWO_PHASE_COMMIT ? _1.TransferFlags.two_phase_commit : 0,
97
+ reserved: 0n,
98
+ pending_id: 0n,
99
+ timeout: IS_TWO_PHASE_TRANSFER ? BigInt(2e9) : 0n,
100
+ ledger: 1,
101
+ code: 1,
102
+ flags: IS_TWO_PHASE_TRANSFER ? _1.TransferFlags.pending : 0,
118
103
  amount: 1n,
119
- timeout: IS_TWO_PHASE_COMMIT ? BigInt(2e9) : 0n,
120
104
  timestamp: 0n,
121
105
  }, i * TRANSFER_SIZE, transferBatch);
122
- if (IS_TWO_PHASE_COMMIT) {
123
- encodeCommit({
124
- id: BigInt(count),
125
- reserved: Buffer.alloc(32, 0),
126
- code: 0,
127
- flags: 0,
106
+ if (IS_TWO_PHASE_TRANSFER) {
107
+ encodeTransfer({
108
+ id: BigInt((MAX_TRANSFERS + count)),
109
+ debit_account_id: accountA.id,
110
+ credit_account_id: accountB.id,
111
+ user_data: 0n,
112
+ reserved: 0n,
113
+ pending_id: BigInt(count),
114
+ timeout: 0n,
115
+ ledger: 1,
116
+ code: 1,
117
+ flags: _1.TransferFlags.post_pending_transfer,
118
+ amount: 1n,
128
119
  timestamp: 0n,
129
- }, i * COMMIT_SIZE, commitBatch);
120
+ }, i * TRANSFER_SIZE, postTransferBatch);
130
121
  }
131
122
  }
132
123
  transfers.push(transferBatch);
133
- if (IS_TWO_PHASE_COMMIT)
134
- commits.push(commitBatch);
124
+ if (IS_TWO_PHASE_TRANSFER)
125
+ posts.push(postTransferBatch);
126
+ if (count % 100)
127
+ console.log(`${Number((count / MAX_TRANSFERS) * 100).toFixed(1)}%`);
135
128
  }
136
- assert_1.default(count === MAX_TRANSFERS);
129
+ (0, assert_1.default)(count === MAX_TRANSFERS);
137
130
  console.log(`starting benchmark. MAX_TRANSFERS=${MAX_TRANSFERS} REQUEST_BATCH_SIZE=${MAX_REQUEST_BATCH_SIZE} NUMBER_OF_BATCHES=${transfers.length}`);
138
131
  let maxCreateTransfersLatency = 0;
139
132
  let maxCommitTransfersLatency = 0;
140
133
  const start = Date.now();
141
134
  for (let i = 0; i < transfers.length; i++) {
142
135
  const ms1 = Date.now();
143
- const transferResults = await rawCreateTransfers(transfers[i]);
144
- assert_1.default(transferResults.length === 0);
136
+ const transferErrors = await rawCreateTransfers(transfers[i]);
137
+ (0, assert_1.default)(transferErrors.length === 0);
145
138
  const ms2 = Date.now();
146
139
  const createTransferLatency = ms2 - ms1;
147
140
  if (createTransferLatency > maxCreateTransfersLatency) {
148
141
  maxCreateTransfersLatency = createTransferLatency;
149
142
  }
150
- if (IS_TWO_PHASE_COMMIT) {
151
- const commitResults = await rawCommitTransfers(commits[i]);
152
- assert_1.default(commitResults.length === 0);
143
+ if (IS_TWO_PHASE_TRANSFER) {
144
+ const commitErrors = await rawCreateTransfers(posts[i]);
145
+ (0, assert_1.default)(commitErrors.length === 0);
153
146
  const ms3 = Date.now();
154
147
  const commitTransferLatency = ms3 - ms2;
155
148
  if (commitTransferLatency > maxCommitTransfersLatency) {
@@ -165,60 +158,69 @@ const runBenchmarkRawReqeust = async () => {
165
158
  };
166
159
  };
167
160
  const runBenchmark = async () => {
168
- console.log(`pre-allocating ${MAX_TRANSFERS} transfers and commits...`);
161
+ console.log(`pre-allocating ${MAX_TRANSFERS} transfers and posts...`);
169
162
  const transfers = [];
170
- const commits = [];
163
+ const posts = [];
171
164
  let count = 0;
172
165
  while (count < MAX_TRANSFERS) {
173
- const transferBatch = [];
174
- const commitBatch = [];
166
+ const pendingBatch = [];
167
+ const postBatch = [];
175
168
  for (let i = 0; i < MAX_REQUEST_BATCH_SIZE; i++) {
176
169
  if (count === MAX_TRANSFERS)
177
170
  break;
178
171
  count += 1;
179
- transferBatch.push({
172
+ pendingBatch.push({
180
173
  id: BigInt(count),
181
174
  debit_account_id: accountA.id,
182
175
  credit_account_id: accountB.id,
183
- code: 0,
184
- reserved: Zeroed32Bytes,
176
+ pending_id: 0n,
177
+ code: 1,
178
+ ledger: 1,
179
+ reserved: 0n,
185
180
  user_data: 0n,
186
- flags: IS_TWO_PHASE_COMMIT ? _1.TransferFlags.two_phase_commit : 0,
181
+ flags: IS_TWO_PHASE_TRANSFER ? _1.TransferFlags.pending : 0,
187
182
  amount: 1n,
188
- timeout: IS_TWO_PHASE_COMMIT ? BigInt(2e9) : 0n,
183
+ timeout: IS_TWO_PHASE_TRANSFER ? BigInt(2e9) : 0n,
189
184
  timestamp: 0n,
190
185
  });
191
- if (IS_TWO_PHASE_COMMIT) {
192
- commitBatch.push({
193
- id: BigInt(count),
194
- reserved: Buffer.alloc(32, 0),
195
- code: 0,
196
- flags: 0,
186
+ if (IS_TWO_PHASE_TRANSFER) {
187
+ postBatch.push({
188
+ id: BigInt(MAX_TRANSFERS + count),
189
+ debit_account_id: accountA.id,
190
+ credit_account_id: accountB.id,
191
+ pending_id: BigInt(count),
192
+ code: 1,
193
+ ledger: 1,
194
+ reserved: 0n,
195
+ user_data: 0n,
196
+ flags: IS_TWO_PHASE_TRANSFER ? _1.TransferFlags.post_pending_transfer : 0,
197
+ amount: 1n,
198
+ timeout: 0n,
197
199
  timestamp: 0n,
198
200
  });
199
201
  }
200
202
  }
201
- transfers.push(transferBatch);
202
- if (IS_TWO_PHASE_COMMIT)
203
- commits.push(commitBatch);
203
+ transfers.push(pendingBatch);
204
+ if (IS_TWO_PHASE_TRANSFER)
205
+ posts.push(postBatch);
204
206
  }
205
- assert_1.default(count === MAX_TRANSFERS);
207
+ (0, assert_1.default)(count === MAX_TRANSFERS);
206
208
  console.log(`starting benchmark. MAX_TRANSFERS=${MAX_TRANSFERS} REQUEST_BATCH_SIZE=${MAX_REQUEST_BATCH_SIZE} NUMBER_OF_BATCHES=${transfers.length}`);
207
209
  let maxCreateTransfersLatency = 0;
208
210
  let maxCommitTransfersLatency = 0;
209
211
  const start = Date.now();
210
212
  for (let i = 0; i < transfers.length; i++) {
211
213
  const ms1 = Date.now();
212
- const transferResults = await client.createTransfers(transfers[i]);
213
- assert_1.default(transferResults.length === 0);
214
+ const transferErrors = await client.createTransfers(transfers[i]);
215
+ (0, assert_1.default)(transferErrors.length === 0);
214
216
  const ms2 = Date.now();
215
217
  const createTransferLatency = ms2 - ms1;
216
218
  if (createTransferLatency > maxCreateTransfersLatency) {
217
219
  maxCreateTransfersLatency = createTransferLatency;
218
220
  }
219
- if (IS_TWO_PHASE_COMMIT) {
220
- const commitResults = await client.commitTransfers(commits[i]);
221
- assert_1.default(commitResults.length === 0);
221
+ if (IS_TWO_PHASE_TRANSFER) {
222
+ const commitErrors = await client.createTransfers(posts[i]);
223
+ (0, assert_1.default)(commitErrors.length === 0);
222
224
  const ms3 = Date.now();
223
225
  const commitTransferLatency = ms3 - ms2;
224
226
  if (commitTransferLatency > maxCommitTransfersLatency) {
@@ -237,19 +239,19 @@ const main = async () => {
237
239
  console.log("creating the accounts...");
238
240
  await client.createAccounts([accountA, accountB]);
239
241
  const accountResults = await client.lookupAccounts([accountA.id, accountB.id]);
240
- assert_1.default(accountResults.length === 2);
241
- assert_1.default(accountResults[0].debits_accepted === 0n);
242
- assert_1.default(accountResults[1].debits_accepted === 0n);
243
- const benchmark = IS_RAW_REQUEST ? await runBenchmarkRawReqeust() : await runBenchmark();
242
+ (0, assert_1.default)(accountResults.length === 2);
243
+ (0, assert_1.default)(accountResults[0].debits_posted === 0n);
244
+ (0, assert_1.default)(accountResults[1].debits_posted === 0n);
245
+ const benchmark = IS_RAW_REQUEST ? await runBenchmarkRawRequest() : await runBenchmark();
244
246
  const accounts = await client.lookupAccounts([accountA.id, accountB.id]);
245
247
  const result = Math.floor((1000 * MAX_TRANSFERS) / benchmark.ms);
246
248
  console.log("=============================");
247
- console.log(`${IS_TWO_PHASE_COMMIT ? 'two-phase ' : ''}transfers per second: ${result}`);
249
+ console.log(`${IS_TWO_PHASE_TRANSFER ? 'two-phase ' : ''}transfers per second: ${result}`);
248
250
  console.log(`create transfers max p100 latency per 10 000 transfers = ${benchmark.maxCreateTransfersLatency}ms`);
249
251
  console.log(`commit transfers max p100 latency per 10 000 transfers = ${benchmark.maxCommitTransfersLatency}ms`);
250
- assert_1.default(accounts.length === 2);
251
- assert_1.default(accounts[0].debits_accepted === BigInt(MAX_TRANSFERS));
252
- assert_1.default(accounts[1].credits_accepted === BigInt(MAX_TRANSFERS));
252
+ (0, assert_1.default)(accounts.length === 2);
253
+ (0, assert_1.default)(accounts[0].debits_posted === BigInt(MAX_TRANSFERS));
254
+ (0, assert_1.default)(accounts[1].credits_posted === BigInt(MAX_TRANSFERS));
253
255
  if (result < PREVIOUS_BENCHMARK * (100 - TOLERANCE) / 100) {
254
256
  console.warn(`There has been a performance regression. Previous benchmark=${PREVIOUS_BENCHMARK}`);
255
257
  }