tigerbeetle-node 0.5.2 → 0.8.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.
Files changed (61) hide show
  1. package/README.md +97 -78
  2. package/dist/benchmark.js +96 -94
  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 +134 -111
  8. package/dist/test.js.map +1 -1
  9. package/package.json +3 -2
  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 +55 -63
  14. package/src/test.ts +146 -125
  15. package/src/tigerbeetle/scripts/benchmark.bat +46 -0
  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 +8 -4
  19. package/src/tigerbeetle/scripts/vopr.bat +47 -47
  20. package/src/tigerbeetle/scripts/vopr.sh +2 -2
  21. package/src/tigerbeetle/src/benchmark.zig +65 -102
  22. package/src/tigerbeetle/src/cli.zig +39 -18
  23. package/src/tigerbeetle/src/config.zig +44 -25
  24. package/src/tigerbeetle/src/demo.zig +2 -15
  25. package/src/tigerbeetle/src/demo_01_create_accounts.zig +10 -10
  26. package/src/tigerbeetle/src/demo_03_create_transfers.zig +5 -3
  27. package/src/tigerbeetle/src/{demo_04_create_transfers_two_phase_commit.zig → demo_04_create_pending_transfers.zig} +18 -12
  28. package/src/tigerbeetle/src/demo_05_post_pending_transfers.zig +37 -0
  29. package/src/tigerbeetle/src/demo_06_void_pending_transfers.zig +24 -0
  30. package/src/tigerbeetle/src/demo_07_lookup_transfers.zig +1 -1
  31. package/src/tigerbeetle/src/io/benchmark.zig +24 -49
  32. package/src/tigerbeetle/src/io/darwin.zig +175 -44
  33. package/src/tigerbeetle/src/io/linux.zig +177 -72
  34. package/src/tigerbeetle/src/io/test.zig +61 -39
  35. package/src/tigerbeetle/src/io/windows.zig +1161 -0
  36. package/src/tigerbeetle/src/io.zig +2 -0
  37. package/src/tigerbeetle/src/main.zig +31 -10
  38. package/src/tigerbeetle/src/message_bus.zig +49 -61
  39. package/src/tigerbeetle/src/message_pool.zig +66 -57
  40. package/src/tigerbeetle/src/ring_buffer.zig +55 -3
  41. package/src/tigerbeetle/src/simulator.zig +108 -12
  42. package/src/tigerbeetle/src/state_machine.zig +1813 -816
  43. package/src/tigerbeetle/src/storage.zig +0 -230
  44. package/src/tigerbeetle/src/test/cluster.zig +168 -38
  45. package/src/tigerbeetle/src/test/message_bus.zig +4 -3
  46. package/src/tigerbeetle/src/test/network.zig +13 -16
  47. package/src/tigerbeetle/src/test/packet_simulator.zig +14 -1
  48. package/src/tigerbeetle/src/test/state_checker.zig +6 -3
  49. package/src/tigerbeetle/src/test/state_machine.zig +8 -7
  50. package/src/tigerbeetle/src/test/storage.zig +99 -40
  51. package/src/tigerbeetle/src/tigerbeetle.zig +108 -101
  52. package/src/tigerbeetle/src/time.zig +58 -11
  53. package/src/tigerbeetle/src/vsr/client.zig +18 -32
  54. package/src/tigerbeetle/src/vsr/clock.zig +1 -1
  55. package/src/tigerbeetle/src/vsr/journal.zig +1388 -464
  56. package/src/tigerbeetle/src/vsr/replica.zig +1340 -576
  57. package/src/tigerbeetle/src/vsr.zig +452 -40
  58. package/src/translate.zig +10 -0
  59. package/src/tigerbeetle/src/demo_05_accept_transfers.zig +0 -23
  60. package/src/tigerbeetle/src/demo_06_reject_transfers.zig +0 -17
  61. package/src/tigerbeetle/src/format_test.zig +0 -69
package/README.md CHANGED
@@ -10,29 +10,16 @@ The following steps will install the `tigerbeetle-node` module to your current w
10
10
 
11
11
  > Your operating system should be Linux (kernel >= v5.6) or macOS. Windows support is not yet available but is in the works.
12
12
 
13
- > Ensure you are not currently in the project (tigerbeetle-node) directory, but the `parent` directory instead;
14
-
15
- ### YARN Package Manager
16
-
17
- ```sh
13
+ ### YARN Package Manager Installation
14
+ ```shell
18
15
  yarn add tigerbeetle-node
19
16
  ```
20
17
  or
21
-
22
- ### NPM Package Manager
23
- ```sh
18
+ ### NPM Package Manager Installation
19
+ ```shell
24
20
  npm install tigerbeetle-node
25
21
  ```
26
22
 
27
- **Development**
28
-
29
- Follow these steps to get up and running when cloning the repo:
30
-
31
- ```sh
32
- git clone --recurse-submodules https://github.com/coilhq/tigerbeetle-node.git
33
- yarn
34
- ```
35
-
36
23
  ## Usage
37
24
  A client needs to be configured with a `cluster_id` and `replica_addresses`.
38
25
  This instantiates the client where memory is allocated to internally buffer events to be sent.
@@ -42,7 +29,7 @@ Future releases will allow multiple client instantiations.
42
29
  import { createClient } from 'tigerbeetle-node'
43
30
 
44
31
  const client = createClient({
45
- cluster_id: 1,
32
+ cluster_id: 0,
46
33
  replica_addresses: ['3001', '3002', '3003']
47
34
  })
48
35
  ```
@@ -55,15 +42,15 @@ This is reflected in the below function interfaces where each one takes in an ar
55
42
  ```js
56
43
  const account = {
57
44
  id: 137n, // u128
58
- user_data: 0n, // u128, opaque third-party identifier to link this account (many-to-one) to an external entity:
45
+ user_data: 0n, // u128, opaque third-party identifier to link this account to an external entity:
59
46
  reserved: Buffer.alloc(48, 0), // [48]u8
60
- unit: 1, // u16, unit of value
47
+ ledger: 1, // u32, ledger value
61
48
  code: 718, // u16, a chart of accounts code describing the type of account (e.g. clearing, settlement)
62
- flags: 0, // u32
63
- debits_reserved: 0n, // u64
64
- debits_accepted: 0n, // u64
65
- credits_reserved: 0n, // u64
66
- credits_accepted: 0n, // u64
49
+ flags: 0, // u16
50
+ debits_pending: 0n, // u64
51
+ debits_posted: 0n, // u64
52
+ credits_pending: 0n, // u64
53
+ credits_posted: 0n, // u64
67
54
  timestamp: 0n, // u64, Reserved: This will be set by the server.
68
55
  }
69
56
 
@@ -88,7 +75,7 @@ The `flags` on an account provide a way for you to enforce policies by toggling
88
75
  |----------|----------------------------------|-----------------------------------------|
89
76
  | `linked` | `debits_must_not_exceed_credits` | `credits_must_not_exceed_debits` |
90
77
 
91
- 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`.
78
+ 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`.
92
79
  ```js
93
80
  enum CreateAccountFlags {
94
81
  linked = (1 << 0),
@@ -100,7 +87,7 @@ The creation of an account can be linked to the successful creation of another b
100
87
  flags |= CreateAccountFlags.debits_must_not_exceed_credits
101
88
  ```
102
89
 
103
- ### Account lookup
90
+ ### Account Lookup
104
91
 
105
92
  The `id` of the account is used for lookups. Only matched accounts are returned.
106
93
  ```js
@@ -112,80 +99,78 @@ The `id` of the account is used for lookups. Only matched accounts are returned.
112
99
  * id: 137n,
113
100
  * user_data: 0n,
114
101
  * reserved: Buffer,
115
- * unit: 1,
102
+ * ledger: 1,
116
103
  * code: 718,
117
104
  * flags: 0,
118
- * debits_reserved: 0n,
119
- * debits_accepted: 0n,
120
- * credits_reserved: 0n,
121
- * credits_accepted: 0n,
105
+ * debits_pending: 0n,
106
+ * debits_posted: 0n,
107
+ * credits_pending: 0n,
108
+ * credits_posted: 0n,
122
109
  * timestamp: 1623062009212508993n,
123
110
  * }]
124
111
  */
125
112
  ```
126
113
 
127
- ### Creating a transfer
114
+ ### Creating a Transfer
128
115
 
129
116
  This creates a journal entry between two accounts.
130
117
  ```js
131
118
  const transfer = {
132
119
  id: 1n, // u128
120
+ // Double-entry accounting:
133
121
  debit_account_id: 1n, // u128
134
122
  credit_account_id: 2n, // u128
135
- user_data: 0n, // u128, opaque third-party identifier to link this transfer (many-to-one) to an external entity
136
- reserved: Buffer.alloc(32, 0), // two-phase condition can go in here
137
- timeout: 0n, // u64, in nano-seconds.
138
- code: 1, // u32, a chart of accounts code describing the reason for the transfer (e.g. deposit, settlement)
139
- flags: 0, // u32
123
+ // Opaque third-party identifier to link this transfer to an external entity:
124
+ user_data: 0n, // u128
125
+ reserved: 0n, // u128
126
+ // Timeout applicable for a pending/2-phase transfer:
127
+ timeout: 0n, // u64, in nano-seconds.
128
+ // Collection of accounts usually grouped by the currency:
129
+ // You can't transfer money between accounts with different ledgers:
130
+ ledger: 720, // u32, ledger for transfer (e.g. currency).
131
+ // Chart of accounts code describing the reason for the transfer:
132
+ code: 1, // u16, (e.g. deposit, settlement)
133
+ flags: 0, // u16
140
134
  amount: 10n, // u64
141
135
  timestamp: 0n, //u64, Reserved: This will be set by the server.
142
136
  }
143
-
144
137
  const errors = await client.createTransfers([transfer])
145
138
  ```
146
- 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.
147
- | bit 0 | bit 1 | bit 2 |
148
- |----------|--------------------|------------------|
149
- | `linked` | `two_phase_commit` | `condition` |
139
+ 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.
150
140
 
151
- 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)).
141
+ Transfers within a batch may also be linked (see [linked events](#linked-events)).
152
142
  ```js
153
- enum CreateTransferFlags {
154
- linked = (1 << 0>>),
155
- two_phase_commit = (1 << 1),
156
- condition = (1 << 2)
143
+ enum TransferFlags {
144
+ linked = (1 << 0),
145
+ pending = (1 << 1),
146
+ post_pending_transfer = (1 << 2),
147
+ void_pending_transfer = (1 << 3)
157
148
  }
158
-
159
- // two-phase transfer
149
+
150
+ // Two-phase transfer (pending):
160
151
  let flags = 0n
161
- flags |= TransferFlags.two_phase_commit
152
+ flags |= TransferFlags.pending
162
153
 
163
- // two-phase transfer with condition supplied in `reserved`
154
+ // Linked two-phase transfer (pending):
164
155
  let flags = 0n
165
- flags |= TransferFlags.two_phase_commit
166
- flags |= TransferFlags.condition
156
+ flags |= TransferFlags.linked
157
+ flags |= TransferFlags.pending
167
158
  ```
168
159
 
169
- ### Committing a transfer
170
-
171
- This is used to commit a two-phase transfer.
172
- | bit 0 | bit 1 | bit 2 |
173
- |----------|----------|------------|
174
- | `linked` | `reject` | `preimage` |
160
+ ### Post a Pending Transfer (2-Phase)
175
161
 
176
- 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.
162
+ 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.
177
163
  ```js
178
- const commit = {
179
- id: 1n, // u128, must correspond to the transfer id
180
- reserved: Buffer.alloc(32, 0), // [32]u8
181
- code: 1, // u32, accounting system code to identify type of transfer
182
- flags: 0, // u32
164
+ const post = {
165
+ id: 2n, // u128, must correspond to the transfer id
166
+ pending_id: 1n, // u128, id of the pending transfer
167
+ flags: TransferFlags.post_pending_transfer, // to void, use [void_pending_transfer]
183
168
  timestamp: 0n, // u64, Reserved: This will be set by the server.
184
169
  }
185
- const errors = await client.commitTransfers([commit])
170
+ const errors = await client.createTransfers([post])
186
171
  ```
187
172
 
188
- ### Linked events
173
+ ### Linked Events
189
174
 
190
175
  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`.
191
176
 
@@ -194,10 +179,10 @@ let batch = []
194
179
  let linkedFlag = 0
195
180
  linkedFlag |= CreateTransferFlags.linked
196
181
 
197
- // An individual transfer (successful)
182
+ // An individual transfer (successful):
198
183
  batch.push({ id: 1n, ... })
199
184
 
200
- // A chain of 4 transfers (the last transfer in the chain closes the chain with linked=false)
185
+ // A chain of 4 transfers (the last transfer in the chain closes the chain with linked=false):
201
186
  batch.push({ id: 2n, ..., flags: linkedFlag }) // Commit/rollback.
202
187
  batch.push({ id: 3n, ..., flags: linkedFlag }) // Commit/rollback.
203
188
  batch.push({ id: 2n, ..., flags: linkedFlag }) // Fail with exists
@@ -207,11 +192,11 @@ batch.push({ id: 4n, ..., flags: 0 }) // Fail without committing.
207
192
  // This should not see any effect from the failed chain above.
208
193
  batch.push({ id: 2n, ..., flags: 0 })
209
194
 
210
- // A chain of 2 transfers (the first transfer fails the chain)
195
+ // A chain of 2 transfers (the first transfer fails the chain):
211
196
  batch.push({ id: 2n, ..., flags: linkedFlag })
212
197
  batch.push({ id: 3n, ..., flags: 0 })
213
198
 
214
- // A chain of 2 transfers (successful)
199
+ // A chain of 2 transfers (successful):
215
200
  batch.push({ id: 3n, ..., flags: linkedFlag })
216
201
  batch.push({ id: 4n, ..., flags: 0 })
217
202
 
@@ -219,13 +204,47 @@ const errors = await client.createTransfers(batch)
219
204
 
220
205
  /**
221
206
  * [
222
- * { index: 1, error: 1 }, // linked_event_failed
223
- * { index: 2, error: 1 }, // linked_event_failed
224
- * { index: 3, error: 2 }, // exists
225
- * { index: 4, error: 1 }, // linked_event_failed
207
+ * { index: 1, error: 1 }, // linked_event_failed
208
+ * { index: 2, error: 1 }, // linked_event_failed
209
+ * { index: 3, error: 25 }, // exists
210
+ * { index: 4, error: 1 }, // linked_event_failed
226
211
  *
227
- * { index: 6, error: 7 }, // exists_with_different_flags
228
- * { index: 7, error: 1 }, // linked_event_failed
212
+ * { index: 6, error: 17 }, // exists_with_different_flags
213
+ * { index: 7, error: 1 }, // linked_event_failed
229
214
  * ]
230
215
  */
231
216
  ```
217
+
218
+ ### Development
219
+
220
+ Follow these steps to get up and running when cloning the repo:
221
+ ```shell
222
+ git clone --recurse-submodules https://github.com/coilhq/tigerbeetle-node.git
223
+ cd tigerbeetle-node/
224
+ yarn install --immutable
225
+ ```
226
+
227
+ Build locally using `yarn`:
228
+ ```shell
229
+ # Run the following from this directory:
230
+ yarn && yarn build
231
+ ```
232
+
233
+ * **Please note: `yarn clean` will remove Zig and NodeAPI C headers, which mean you need to run:**
234
+ ```shell
235
+ ./scripts/postinstall.sh #Install Zig and NodeJS C Headers
236
+ ```
237
+
238
+ ***Yarn - Run Test***
239
+ Ensure TigerBeetle (`init` & `start`) is running on the port configured in `test.ts`, then run:
240
+ ```shell
241
+ ./tigerbeetle init --cluster=1 --replica=0 --directory=.
242
+ ./tigerbeetle start --cluster=1 --replica=0 --directory=. --addresses=3001
243
+ yarn test
244
+ ```
245
+
246
+ ***Yarn - Run Benchmark***
247
+ Run the benchmark (The `benchmark` will automatically start TigerBeetle on port `3001` _(single replica)_:
248
+ ```shell
249
+ yarn benchmark
250
+ ```
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
16
  const client = _1.createClient({
17
- cluster_id: 1,
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
+ 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 () => {
79
+ const runBenchmarkRawRequest = async () => {
98
80
  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...`);
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,27 +93,38 @@ 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
129
  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}`);
@@ -140,16 +133,16 @@ const runBenchmarkRawReqeust = async () => {
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
+ 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
+ assert_1.default(commitErrors.length === 0);
153
146
  const ms3 = Date.now();
154
147
  const commitTransferLatency = ms3 - ms2;
155
148
  if (commitTransferLatency > maxCommitTransfersLatency) {
@@ -165,42 +158,51 @@ 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
207
  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}`);
@@ -209,16 +211,16 @@ const runBenchmark = async () => {
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
+ 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
+ assert_1.default(commitErrors.length === 0);
222
224
  const ms3 = Date.now();
223
225
  const commitTransferLatency = ms3 - ms2;
224
226
  if (commitTransferLatency > maxCommitTransfersLatency) {
@@ -238,18 +240,18 @@ const main = async () => {
238
240
  await client.createAccounts([accountA, accountB]);
239
241
  const accountResults = await client.lookupAccounts([accountA.id, accountB.id]);
240
242
  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();
243
+ assert_1.default(accountResults[0].debits_posted === 0n);
244
+ 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
252
  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));
253
+ assert_1.default(accounts[0].debits_posted === BigInt(MAX_TRANSFERS));
254
+ 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
  }