tigerbeetle-node 0.10.0 → 0.11.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/README.md +302 -101
- package/dist/index.d.ts +70 -72
- package/dist/index.js +70 -72
- package/dist/index.js.map +1 -1
- package/package.json +9 -8
- package/scripts/download_node_headers.sh +14 -7
- package/src/index.ts +6 -10
- package/src/node.zig +6 -3
- package/src/tigerbeetle/scripts/benchmark.sh +4 -4
- package/src/tigerbeetle/scripts/confirm_image.sh +44 -0
- package/src/tigerbeetle/scripts/fuzz_loop.sh +15 -0
- package/src/tigerbeetle/scripts/fuzz_unique_errors.sh +7 -0
- package/src/tigerbeetle/scripts/install.sh +19 -4
- package/src/tigerbeetle/scripts/install_zig.bat +5 -1
- package/src/tigerbeetle/scripts/install_zig.sh +24 -14
- package/src/tigerbeetle/scripts/pre-commit.sh +9 -0
- package/src/tigerbeetle/scripts/shellcheck.sh +5 -0
- package/src/tigerbeetle/scripts/tests_on_alpine.sh +10 -0
- package/src/tigerbeetle/scripts/tests_on_ubuntu.sh +14 -0
- package/src/tigerbeetle/scripts/validate_docs.sh +17 -0
- package/src/tigerbeetle/src/benchmark.zig +29 -13
- package/src/tigerbeetle/src/c/tb_client/context.zig +248 -47
- package/src/tigerbeetle/src/c/tb_client/echo_client.zig +108 -0
- package/src/tigerbeetle/src/c/tb_client/packet.zig +2 -2
- package/src/tigerbeetle/src/c/tb_client/signal.zig +2 -4
- package/src/tigerbeetle/src/c/tb_client/thread.zig +17 -257
- package/src/tigerbeetle/src/c/tb_client.h +118 -84
- package/src/tigerbeetle/src/c/tb_client.zig +88 -23
- package/src/tigerbeetle/src/c/tb_client_header_test.zig +135 -0
- package/src/tigerbeetle/src/c/test.zig +371 -1
- package/src/tigerbeetle/src/cli.zig +37 -7
- package/src/tigerbeetle/src/config.zig +58 -17
- package/src/tigerbeetle/src/demo.zig +5 -2
- package/src/tigerbeetle/src/demo_01_create_accounts.zig +1 -1
- package/src/tigerbeetle/src/demo_03_create_transfers.zig +13 -0
- package/src/tigerbeetle/src/ewah.zig +11 -33
- package/src/tigerbeetle/src/ewah_benchmark.zig +8 -9
- package/src/tigerbeetle/src/io/linux.zig +1 -1
- package/src/tigerbeetle/src/lsm/README.md +308 -0
- package/src/tigerbeetle/src/lsm/binary_search.zig +137 -10
- package/src/tigerbeetle/src/lsm/bloom_filter.zig +43 -0
- package/src/tigerbeetle/src/lsm/compaction.zig +376 -397
- package/src/tigerbeetle/src/lsm/composite_key.zig +2 -0
- package/src/tigerbeetle/src/lsm/eytzinger.zig +1 -1
- package/src/tigerbeetle/src/{eytzinger_benchmark.zig → lsm/eytzinger_benchmark.zig} +34 -21
- package/src/tigerbeetle/src/lsm/forest.zig +21 -447
- package/src/tigerbeetle/src/lsm/forest_fuzz.zig +414 -0
- package/src/tigerbeetle/src/lsm/grid.zig +170 -76
- package/src/tigerbeetle/src/lsm/groove.zig +197 -133
- package/src/tigerbeetle/src/lsm/k_way_merge.zig +40 -18
- package/src/tigerbeetle/src/lsm/level_iterator.zig +28 -9
- package/src/tigerbeetle/src/lsm/manifest.zig +93 -180
- package/src/tigerbeetle/src/lsm/manifest_level.zig +161 -454
- package/src/tigerbeetle/src/lsm/manifest_log.zig +243 -356
- package/src/tigerbeetle/src/lsm/manifest_log_fuzz.zig +665 -0
- package/src/tigerbeetle/src/lsm/node_pool.zig +4 -0
- package/src/tigerbeetle/src/lsm/posted_groove.zig +65 -76
- package/src/tigerbeetle/src/lsm/segmented_array.zig +580 -251
- package/src/tigerbeetle/src/lsm/segmented_array_benchmark.zig +148 -0
- package/src/tigerbeetle/src/lsm/segmented_array_fuzz.zig +9 -0
- package/src/tigerbeetle/src/lsm/set_associative_cache.zig +62 -12
- package/src/tigerbeetle/src/lsm/table.zig +115 -68
- package/src/tigerbeetle/src/lsm/table_immutable.zig +30 -23
- package/src/tigerbeetle/src/lsm/table_iterator.zig +27 -17
- package/src/tigerbeetle/src/lsm/table_mutable.zig +63 -12
- package/src/tigerbeetle/src/lsm/test.zig +61 -56
- package/src/tigerbeetle/src/lsm/tree.zig +450 -407
- package/src/tigerbeetle/src/lsm/tree_fuzz.zig +461 -0
- package/src/tigerbeetle/src/main.zig +83 -8
- package/src/tigerbeetle/src/message_bus.zig +20 -9
- package/src/tigerbeetle/src/message_pool.zig +22 -19
- package/src/tigerbeetle/src/ring_buffer.zig +7 -3
- package/src/tigerbeetle/src/simulator.zig +179 -119
- package/src/tigerbeetle/src/state_machine.zig +381 -246
- package/src/tigerbeetle/src/static_allocator.zig +65 -0
- package/src/tigerbeetle/src/storage.zig +3 -7
- package/src/tigerbeetle/src/test/accounting/auditor.zig +577 -0
- package/src/tigerbeetle/src/test/accounting/workload.zig +823 -0
- package/src/tigerbeetle/src/test/cluster.zig +33 -81
- package/src/tigerbeetle/src/test/conductor.zig +366 -0
- package/src/tigerbeetle/src/test/fuzz.zig +121 -0
- package/src/tigerbeetle/src/test/id.zig +89 -0
- package/src/tigerbeetle/src/test/network.zig +45 -19
- package/src/tigerbeetle/src/test/packet_simulator.zig +40 -29
- package/src/tigerbeetle/src/test/priority_queue.zig +645 -0
- package/src/tigerbeetle/src/test/state_checker.zig +91 -69
- package/src/tigerbeetle/src/test/state_machine.zig +11 -35
- package/src/tigerbeetle/src/test/storage.zig +470 -106
- package/src/tigerbeetle/src/test/storage_checker.zig +204 -0
- package/src/tigerbeetle/src/tigerbeetle.zig +15 -16
- package/src/tigerbeetle/src/unit_tests.zig +13 -1
- package/src/tigerbeetle/src/util.zig +97 -11
- package/src/tigerbeetle/src/vopr.zig +495 -0
- package/src/tigerbeetle/src/vsr/client.zig +21 -3
- package/src/tigerbeetle/src/vsr/journal.zig +293 -212
- package/src/tigerbeetle/src/vsr/replica.zig +1086 -515
- package/src/tigerbeetle/src/vsr/superblock.zig +382 -637
- package/src/tigerbeetle/src/vsr/superblock_client_table.zig +14 -16
- package/src/tigerbeetle/src/vsr/superblock_free_set.zig +416 -153
- package/src/tigerbeetle/src/vsr/superblock_free_set_fuzz.zig +332 -0
- package/src/tigerbeetle/src/vsr/superblock_fuzz.zig +349 -0
- package/src/tigerbeetle/src/vsr/superblock_manifest.zig +62 -12
- package/src/tigerbeetle/src/vsr/superblock_quorums.zig +394 -0
- package/src/tigerbeetle/src/vsr/superblock_quorums_fuzz.zig +312 -0
- package/src/tigerbeetle/src/vsr.zig +94 -60
- package/src/tigerbeetle/scripts/vopr.bat +0 -48
- package/src/tigerbeetle/scripts/vopr.sh +0 -33
- package/src/tigerbeetle/src/benchmark_array_search.zig +0 -317
- package/src/tigerbeetle/src/benchmarks/perf.zig +0 -299
|
@@ -7,7 +7,6 @@
|
|
|
7
7
|
|
|
8
8
|
typedef __uint128_t tb_uint128_t;
|
|
9
9
|
|
|
10
|
-
|
|
11
10
|
typedef enum TB_ACCOUNT_FLAGS {
|
|
12
11
|
TB_ACCOUNT_LINKED = 1 << 0,
|
|
13
12
|
TB_ACCOUNT_DEBITS_MUST_NOT_EXCEED_CREDITS = 1 << 1,
|
|
@@ -18,20 +17,21 @@ typedef struct tb_account_t {
|
|
|
18
17
|
tb_uint128_t id;
|
|
19
18
|
tb_uint128_t user_data;
|
|
20
19
|
uint8_t reserved[48];
|
|
21
|
-
|
|
20
|
+
uint32_t ledger;
|
|
22
21
|
uint16_t code;
|
|
23
|
-
|
|
24
|
-
uint64_t
|
|
25
|
-
uint64_t
|
|
26
|
-
uint64_t
|
|
27
|
-
uint64_t
|
|
22
|
+
uint16_t flags;
|
|
23
|
+
uint64_t debits_pending;
|
|
24
|
+
uint64_t debits_posted;
|
|
25
|
+
uint64_t credits_pending;
|
|
26
|
+
uint64_t credits_posted;
|
|
28
27
|
uint64_t timestamp;
|
|
29
28
|
} tb_account_t;
|
|
30
29
|
|
|
31
30
|
typedef enum TB_TRANSFER_FLAGS {
|
|
32
31
|
TB_TRANSFER_LINKED = 1 << 0,
|
|
33
|
-
|
|
34
|
-
|
|
32
|
+
TB_TRANSFER_PENDING = 1 << 1,
|
|
33
|
+
TB_TRANSFER_POST_PENDING_TRANSFER = 1 << 2,
|
|
34
|
+
TB_TRANSFER_VOID_PENDING_TRANSFER = 1 << 3,
|
|
35
35
|
} TB_TRANSFER_FLAGS;
|
|
36
36
|
|
|
37
37
|
typedef struct tb_transfer_t {
|
|
@@ -39,111 +39,132 @@ typedef struct tb_transfer_t {
|
|
|
39
39
|
tb_uint128_t debit_account_id;
|
|
40
40
|
tb_uint128_t credit_account_id;
|
|
41
41
|
tb_uint128_t user_data;
|
|
42
|
-
|
|
42
|
+
tb_uint128_t reserved;
|
|
43
|
+
tb_uint128_t pending_id;
|
|
43
44
|
uint64_t timeout;
|
|
44
|
-
uint32_t
|
|
45
|
-
|
|
45
|
+
uint32_t ledger;
|
|
46
|
+
uint16_t code;
|
|
47
|
+
uint16_t flags;
|
|
46
48
|
uint64_t amount;
|
|
47
49
|
uint64_t timestamp;
|
|
48
50
|
} tb_transfer_t;
|
|
49
51
|
|
|
50
|
-
typedef enum TB_COMMIT_FLAGS {
|
|
51
|
-
TB_COMMIT_LINKED = 1 << 0,
|
|
52
|
-
TB_COMMIT_REJECT = 1 << 1,
|
|
53
|
-
TB_COMMIT_PREIMAGE = 1 << 2,
|
|
54
|
-
} TB_COMMIT_FLAGS;
|
|
55
|
-
|
|
56
|
-
typedef struct tb_commit_t {
|
|
57
|
-
tb_uint128_t id;
|
|
58
|
-
uint8_t reserved[32];
|
|
59
|
-
uint32_t code;
|
|
60
|
-
uint32_t flags;
|
|
61
|
-
uint64_t timestamp;
|
|
62
|
-
} tb_commit_t;
|
|
63
|
-
|
|
64
52
|
typedef enum TB_CREATE_ACCOUNT_RESULT {
|
|
65
53
|
TB_CREATE_ACCOUNT_OK,
|
|
66
54
|
TB_CREATE_ACCOUNT_LINKED_EVENT_FAILED,
|
|
67
|
-
|
|
55
|
+
TB_CREATE_ACCOUNT_LINKED_EVENT_CHAIN_OPEN,
|
|
56
|
+
|
|
57
|
+
TB_CREATE_ACCOUNT_RESERVED_FLAG,
|
|
58
|
+
TB_CREATE_ACCOUNT_RESERVED_FIELD,
|
|
59
|
+
|
|
60
|
+
TB_CREATE_ACCOUNT_ID_MUST_NOT_BE_ZERO,
|
|
61
|
+
TB_CREATE_ACCOUNT_ID_MUST_NOT_BE_INT_MAX,
|
|
62
|
+
TB_CREATE_ACCOUNT_LEDGER_MUST_NOT_BE_ZERO,
|
|
63
|
+
TB_CREATE_ACCOUNT_CODE_MUST_NOT_BE_ZERO,
|
|
64
|
+
TB_CREATE_ACCOUNT_DEBITS_PENDING_MUST_BE_ZERO,
|
|
65
|
+
TB_CREATE_ACCOUNT_DEBITS_POSTED_MUST_BE_ZERO,
|
|
66
|
+
TB_CREATE_ACCOUNT_CREDITS_PENDING_MUST_BE_ZERO,
|
|
67
|
+
TB_CREATE_ACCOUNT_CREDITS_POSTED_MUST_BE_ZERO,
|
|
68
|
+
|
|
69
|
+
TB_CREATE_ACCOUNT_MUTUALLY_EXCLUSIVE_FLAGS,
|
|
70
|
+
|
|
71
|
+
TB_CREATE_ACCOUNT_EXISTS_WITH_DIFFERENT_FLAGS,
|
|
68
72
|
TB_CREATE_ACCOUNT_EXISTS_WITH_DIFFERENT_USER_DATA,
|
|
69
|
-
|
|
70
|
-
TB_CREATE_ACCOUNT_EXISTS_WITH_DIFFERENT_UNIT,
|
|
73
|
+
TB_CREATE_ACCOUNT_EXISTS_WITH_DIFFERENT_LEDGER,
|
|
71
74
|
TB_CREATE_ACCOUNT_EXISTS_WITH_DIFFERENT_CODE,
|
|
72
|
-
|
|
73
|
-
TB_CREATE_ACCOUNT_EXCEEDS_CREDITS,
|
|
74
|
-
TB_CREATE_ACCOUNT_EXCEEDS_DEBITS,
|
|
75
|
-
TB_CREATE_ACCOUNT_RESERVE_FAILED,
|
|
76
|
-
TB_CREATE_ACCOUNT_RESERVE_FLAG_PADDING
|
|
75
|
+
TB_CREATE_ACCOUNT_EXISTS
|
|
77
76
|
} TB_CREATE_ACCOUNT_RESULT;
|
|
78
77
|
|
|
79
78
|
typedef enum TB_CREATE_TRANSFER_RESULT {
|
|
80
79
|
TB_CREATE_TRANSFER_OK,
|
|
81
80
|
TB_CREATE_TRANSFER_LINKED_EVENT_FAILED,
|
|
82
|
-
|
|
81
|
+
TB_CREATE_TRANSFER_LINKED_EVENT_CHAIN_OPEN,
|
|
82
|
+
|
|
83
|
+
TB_CREATE_TRANSFER_RESERVED_FLAG,
|
|
84
|
+
TB_CREATE_TRANSFER_RESERVED_FIELD,
|
|
85
|
+
|
|
86
|
+
TB_CREATE_TRANSFER_ID_MUST_NOT_BE_ZERO,
|
|
87
|
+
TB_CREATE_TRANSFER_ID_MUST_NOT_BE_INT_MAX,
|
|
88
|
+
TB_CREATE_TRANSFER_DEBIT_ACCOUNT_ID_MUST_NOT_BE_ZERO,
|
|
89
|
+
TB_CREATE_TRANSFER_DEBIT_ACCOUNT_ID_MUST_NOT_BE_INT_MAX,
|
|
90
|
+
TB_CREATE_TRANSFER_CREDIT_ACCOUNT_ID_MUST_NOT_BE_ZERO,
|
|
91
|
+
TB_CREATE_TRANSFER_CREDIT_ACCOUNT_ID_MUST_NOT_BE_INT_MAX,
|
|
92
|
+
TB_CREATE_TRANSFER_ACCOUNTS_MUST_BE_DIFFERENT,
|
|
93
|
+
|
|
94
|
+
TB_CREATE_TRANSFER_PENDING_ID_MUST_BE_ZERO,
|
|
95
|
+
TB_CREATE_TRANSFER_PENDING_TRANSFER_MUST_TIMEOUT,
|
|
96
|
+
|
|
97
|
+
TB_CREATE_TRANSFER_LEDGER_MUST_NOT_BE_ZERO,
|
|
98
|
+
TB_CREATE_TRANSFER_CODE_MUST_NOT_BE_ZERO,
|
|
99
|
+
TB_CREATE_TRANSFER_AMOUNT_MUST_NOT_BE_ZERO,
|
|
100
|
+
|
|
101
|
+
TB_CREATE_TRANSFER_DEBIT_ACCOUNT_NOT_FOUND,
|
|
102
|
+
TB_CREATE_TRANSFER_CREDIT_ACCOUNT_NOT_FOUND,
|
|
103
|
+
|
|
104
|
+
TB_CREATE_TRANSFER_ACCOUNTS_MUST_HAVE_THE_SAME_LEDGER,
|
|
105
|
+
TB_CREATE_TRANSFER_TRANSFER_MUST_HAVE_THE_SAME_LEDGER_AS_ACCOUNTS,
|
|
106
|
+
|
|
107
|
+
TB_CREATE_TRANSFER_EXISTS_WITH_DIFFERENT_FLAGS,
|
|
83
108
|
TB_CREATE_TRANSFER_EXISTS_WITH_DIFFERENT_DEBIT_ACCOUNT_ID,
|
|
84
109
|
TB_CREATE_TRANSFER_EXISTS_WITH_DIFFERENT_CREDIT_ACCOUNT_ID,
|
|
85
110
|
TB_CREATE_TRANSFER_EXISTS_WITH_DIFFERENT_USER_DATA,
|
|
86
|
-
|
|
111
|
+
TB_CREATE_TRANSFER_EXISTS_WITH_DIFFERENT_PENDING_ID,
|
|
112
|
+
TB_CREATE_TRANSFER_EXISTS_WITH_DIFFERENT_TIMEOUT,
|
|
87
113
|
TB_CREATE_TRANSFER_EXISTS_WITH_DIFFERENT_CODE,
|
|
88
114
|
TB_CREATE_TRANSFER_EXISTS_WITH_DIFFERENT_AMOUNT,
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
TB_CREATE_TRANSFER_AMOUNT_IS_ZERO,
|
|
115
|
+
TB_CREATE_TRANSFER_EXISTS,
|
|
116
|
+
|
|
117
|
+
TB_CREATE_TRANSFER_OVERFLOWS_DEBITS_PENDING,
|
|
118
|
+
TB_CREATE_TRANSFER_OVERFLOWS_CREDITS_PENDING,
|
|
119
|
+
TB_CREATE_TRANSFER_OVERFLOWS_DEBITS_POSTED,
|
|
120
|
+
TB_CREATE_TRANSFER_OVERFLOWS_CREDITS_POSTED,
|
|
121
|
+
TB_CREATE_TRANSFER_OVERFLOWS_DEBITS,
|
|
122
|
+
TB_CREATE_TRANSFER_OVERFLOWS_CREDITS,
|
|
123
|
+
TB_CREATE_TRANSFER_OVERFLOWS_TIMEOUT,
|
|
124
|
+
|
|
100
125
|
TB_CREATE_TRANSFER_EXCEEDS_CREDITS,
|
|
101
126
|
TB_CREATE_TRANSFER_EXCEEDS_DEBITS,
|
|
102
|
-
TB_CREATE_TRANSFER_TWO_PHASE_COMMIT_MUST_TIMEOUT,
|
|
103
|
-
TB_CREATE_TRANSFER_TIMEOUT_RESERVED_FOR_TWO_PHASE_COMMIT
|
|
104
|
-
} TB_CREATE_TRANSFER_RESULT;
|
|
105
127
|
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
128
|
+
TB_CREATE_TRANSFER_CANNOT_POST_AND_VOID_PENDING_TRANSFER,
|
|
129
|
+
TB_CREATE_TRANSFER_PENDING_TRANSFER_CANNOT_POST_OR_VOID_ANOTHER,
|
|
130
|
+
TB_CREATE_TRANSFER_TIMEOUT_RESERVED_FOR_PENDING_TRANSFER,
|
|
131
|
+
|
|
132
|
+
TB_CREATE_TRANSFER_PENDING_ID_MUST_NOT_BE_ZERO,
|
|
133
|
+
TB_CREATE_TRANSFER_PENDING_ID_MUST_NOT_BE_INT_MAX,
|
|
134
|
+
TB_CREATE_TRANSFER_PENDING_ID_MUST_BE_DIFFERENT,
|
|
135
|
+
|
|
136
|
+
TB_CREATE_TRANSFER_PENDING_TRANSFER_NOT_FOUND,
|
|
137
|
+
TB_CREATE_TRANSFER_PENDING_TRANSFER_NOT_PENDING,
|
|
138
|
+
|
|
139
|
+
TB_CREATE_TRANSFER_PENDING_TRANSFER_HAS_DIFFERENT_DEBIT_ACCOUNT_ID,
|
|
140
|
+
TB_CREATE_TRANSFER_PENDING_TRANSFER_HAS_DIFFERENT_CREDIT_ACCOUNT_ID,
|
|
141
|
+
TB_CREATE_TRANSFER_PENDING_TRANSFER_HAS_DIFFERENT_LEDGER,
|
|
142
|
+
TB_CREATE_TRANSFER_PENDING_TRANSFER_HAS_DIFFERENT_CODE,
|
|
143
|
+
|
|
144
|
+
TB_CREATE_TRANSFER_EXCEEDS_PENDING_TRANSFER_AMOUNT,
|
|
145
|
+
TB_CREATE_TRANSFER_PENDING_TRANSFER_HAS_DIFFERENT_AMOUNT,
|
|
146
|
+
|
|
147
|
+
TB_CREATE_TRANSFER_PENDING_TRANSFER_ALREADY_POSTED,
|
|
148
|
+
TB_CREATE_TRANSFER_PENDING_TRANSFER_ALREADY_VOIDED,
|
|
149
|
+
|
|
150
|
+
TB_CREATE_TRANSFER_PENDING_TRANSFER_EXPIRED,
|
|
151
|
+
} TB_CREATE_TRANSFER_RESULT;
|
|
125
152
|
|
|
126
153
|
typedef struct tb_create_accounts_result_t {
|
|
127
154
|
uint32_t index;
|
|
128
|
-
|
|
155
|
+
uint32_t result;
|
|
129
156
|
} tb_create_accounts_result_t;
|
|
130
157
|
|
|
131
158
|
typedef struct tb_create_transfers_result_t {
|
|
132
159
|
uint32_t index;
|
|
133
|
-
|
|
160
|
+
uint32_t result;
|
|
134
161
|
} tb_create_transfers_result_t;
|
|
135
162
|
|
|
136
|
-
typedef struct tb_commit_transfers_result_t {
|
|
137
|
-
uint32_t index;
|
|
138
|
-
TB_COMMIT_TRANSFER_RESULT result;
|
|
139
|
-
} tb_commit_transfers_result_t;
|
|
140
|
-
|
|
141
163
|
typedef enum TB_OPERATION {
|
|
142
164
|
TB_OP_CREATE_ACCOUNTS = 3,
|
|
143
165
|
TB_OP_CREATE_TRANSFERS = 4,
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
TB_OP_LOOKUP_TRANSFERS = 7
|
|
166
|
+
TB_OP_LOOKUP_ACCOUNTS = 5,
|
|
167
|
+
TB_OP_LOOKUP_TRANSFERS = 6
|
|
147
168
|
} TB_OPERATION;
|
|
148
169
|
|
|
149
170
|
typedef enum TB_PACKET_STATUS {
|
|
@@ -173,9 +194,11 @@ typedef enum TB_STATUS {
|
|
|
173
194
|
TB_STATUS_SUCCESS = 0,
|
|
174
195
|
TB_STATUS_UNEXPECTED = 1,
|
|
175
196
|
TB_STATUS_OUT_OF_MEMORY = 2,
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
197
|
+
TB_STATUS_ADDRESS_INVALID = 3,
|
|
198
|
+
TB_STATUS_ADDRESS_LIMIT_EXCEEDED = 4,
|
|
199
|
+
TB_STATUS_PACKETS_COUNT_INVALID = 5,
|
|
200
|
+
TB_STATUS_SYSTEM_RESOURCES = 6,
|
|
201
|
+
TB_STATUS_NETWORK_SUBSYSTEM = 7,
|
|
179
202
|
} TB_STATUS;
|
|
180
203
|
|
|
181
204
|
TB_STATUS tb_client_init(
|
|
@@ -184,7 +207,18 @@ TB_STATUS tb_client_init(
|
|
|
184
207
|
uint32_t cluster_id,
|
|
185
208
|
const char* address_ptr,
|
|
186
209
|
uint32_t address_len,
|
|
187
|
-
uint32_t
|
|
210
|
+
uint32_t packets_count,
|
|
211
|
+
uintptr_t on_completion_ctx,
|
|
212
|
+
void (*on_completion_fn)(uintptr_t, tb_client_t, tb_packet_t*, const uint8_t*, uint32_t)
|
|
213
|
+
);
|
|
214
|
+
|
|
215
|
+
TB_STATUS tb_client_init_echo(
|
|
216
|
+
tb_client_t* out_client,
|
|
217
|
+
tb_packet_list_t* out_packets,
|
|
218
|
+
uint32_t cluster_id,
|
|
219
|
+
const char* address_ptr,
|
|
220
|
+
uint32_t address_len,
|
|
221
|
+
uint32_t packets_count,
|
|
188
222
|
uintptr_t on_completion_ctx,
|
|
189
223
|
void (*on_completion_fn)(uintptr_t, tb_client_t, tb_packet_t*, const uint8_t*, uint32_t)
|
|
190
224
|
);
|
|
@@ -198,4 +232,4 @@ void tb_client_deinit(
|
|
|
198
232
|
tb_client_t client
|
|
199
233
|
);
|
|
200
234
|
|
|
201
|
-
#endif // TB_CLIENT_C
|
|
235
|
+
#endif // TB_CLIENT_C
|
|
@@ -10,7 +10,9 @@ pub const tb_status_t = enum(c_int) {
|
|
|
10
10
|
success = 0,
|
|
11
11
|
unexpected,
|
|
12
12
|
out_of_memory,
|
|
13
|
-
|
|
13
|
+
address_invalid,
|
|
14
|
+
address_limit_exceeded,
|
|
15
|
+
packets_count_invalid,
|
|
14
16
|
system_resources,
|
|
15
17
|
network_subsystem,
|
|
16
18
|
};
|
|
@@ -23,9 +25,26 @@ pub const tb_completion_t = fn (
|
|
|
23
25
|
result_len: u32,
|
|
24
26
|
) callconv(.C) void;
|
|
25
27
|
|
|
28
|
+
const config = @import("../config.zig");
|
|
29
|
+
const Storage = @import("../storage.zig").Storage;
|
|
30
|
+
const MessageBus = @import("../message_bus.zig").MessageBusClient;
|
|
31
|
+
const StateMachine = @import("../state_machine.zig").StateMachineType(Storage, .{
|
|
32
|
+
.message_body_size_max = config.message_body_size_max,
|
|
33
|
+
});
|
|
34
|
+
|
|
26
35
|
const ContextType = @import("tb_client/context.zig").ContextType;
|
|
27
36
|
const ContextImplementation = @import("tb_client/context.zig").ContextImplementation;
|
|
28
37
|
|
|
38
|
+
const DefaultContext = blk: {
|
|
39
|
+
const Client = @import("../vsr/client.zig").Client(StateMachine, MessageBus);
|
|
40
|
+
break :blk ContextType(Client);
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
const TestingContext = blk: {
|
|
44
|
+
const EchoClient = @import("tb_client/echo_client.zig").EchoClient(StateMachine, MessageBus);
|
|
45
|
+
break :blk ContextType(EchoClient);
|
|
46
|
+
};
|
|
47
|
+
|
|
29
48
|
pub fn context_to_client(implementation: *ContextImplementation) tb_client_t {
|
|
30
49
|
return @ptrCast(tb_client_t, implementation);
|
|
31
50
|
}
|
|
@@ -34,21 +53,10 @@ fn client_to_context(tb_client: tb_client_t) *ContextImplementation {
|
|
|
34
53
|
return @ptrCast(*ContextImplementation, @alignCast(@alignOf(ContextImplementation), tb_client));
|
|
35
54
|
}
|
|
36
55
|
|
|
37
|
-
const DefaultContext = blk: {
|
|
38
|
-
const Storage = @import("../storage.zig").Storage;
|
|
39
|
-
const MessageBus = @import("../message_bus.zig").MessageBusClient;
|
|
40
|
-
const StateMachine = @import("../state_machine.zig").StateMachineType(Storage);
|
|
41
|
-
break :blk ContextType(StateMachine, MessageBus);
|
|
42
|
-
};
|
|
43
|
-
|
|
44
|
-
// const TestingContext = blk: {
|
|
45
|
-
// const MessageBus = @import("test_message_bus.zig").MessageBusClient;
|
|
46
|
-
// const StateMachine = @import("../state_machine.zig").StateMachine;
|
|
47
|
-
// break :blk ContextType(StateMachine, MessageBus);
|
|
48
|
-
// };
|
|
49
|
-
|
|
50
56
|
// Pick the most suitable allocator
|
|
51
|
-
const global_allocator = if (builtin.
|
|
57
|
+
const global_allocator = if (builtin.is_test)
|
|
58
|
+
std.testing.allocator
|
|
59
|
+
else if (builtin.link_libc)
|
|
52
60
|
std.heap.c_allocator
|
|
53
61
|
else if (builtin.target.os.tag == .windows)
|
|
54
62
|
(struct {
|
|
@@ -63,28 +71,85 @@ pub export fn tb_client_init(
|
|
|
63
71
|
cluster_id: u32,
|
|
64
72
|
addresses_ptr: [*:0]const u8,
|
|
65
73
|
addresses_len: u32,
|
|
66
|
-
|
|
74
|
+
packets_count: u32,
|
|
67
75
|
on_completion_ctx: usize,
|
|
68
76
|
on_completion_fn: tb_completion_t,
|
|
69
77
|
) tb_status_t {
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
78
|
+
return init(
|
|
79
|
+
DefaultContext,
|
|
80
|
+
out_client,
|
|
81
|
+
out_packets,
|
|
82
|
+
cluster_id,
|
|
83
|
+
addresses_ptr,
|
|
84
|
+
addresses_len,
|
|
85
|
+
packets_count,
|
|
86
|
+
on_completion_ctx,
|
|
87
|
+
on_completion_fn,
|
|
88
|
+
);
|
|
89
|
+
}
|
|
74
90
|
|
|
75
|
-
|
|
76
|
-
|
|
91
|
+
pub export fn tb_client_init_echo(
|
|
92
|
+
out_client: *tb_client_t,
|
|
93
|
+
out_packets: *tb_packet_list_t,
|
|
94
|
+
cluster_id: u32,
|
|
95
|
+
addresses_ptr: [*:0]const u8,
|
|
96
|
+
addresses_len: u32,
|
|
97
|
+
packets_count: u32,
|
|
98
|
+
on_completion_ctx: usize,
|
|
99
|
+
on_completion_fn: tb_completion_t,
|
|
100
|
+
) tb_status_t {
|
|
101
|
+
return init(
|
|
102
|
+
TestingContext,
|
|
77
103
|
out_client,
|
|
78
104
|
out_packets,
|
|
79
105
|
cluster_id,
|
|
80
106
|
addresses_ptr,
|
|
81
107
|
addresses_len,
|
|
82
|
-
|
|
108
|
+
packets_count,
|
|
83
109
|
on_completion_ctx,
|
|
84
110
|
on_completion_fn,
|
|
85
111
|
);
|
|
86
112
|
}
|
|
87
113
|
|
|
114
|
+
fn init(
|
|
115
|
+
comptime Context: type,
|
|
116
|
+
out_client: *tb_client_t,
|
|
117
|
+
out_packets: *tb_packet_list_t,
|
|
118
|
+
cluster_id: u32,
|
|
119
|
+
addresses_ptr: [*:0]const u8,
|
|
120
|
+
addresses_len: u32,
|
|
121
|
+
packets_count: u32,
|
|
122
|
+
on_completion_ctx: usize,
|
|
123
|
+
on_completion_fn: tb_completion_t,
|
|
124
|
+
) tb_status_t {
|
|
125
|
+
const addresses = @ptrCast([*]const u8, addresses_ptr)[0..addresses_len];
|
|
126
|
+
const context = Context.init(
|
|
127
|
+
global_allocator,
|
|
128
|
+
cluster_id,
|
|
129
|
+
addresses,
|
|
130
|
+
packets_count,
|
|
131
|
+
on_completion_ctx,
|
|
132
|
+
on_completion_fn,
|
|
133
|
+
) catch |err| switch (err) {
|
|
134
|
+
error.Unexpected => return .unexpected,
|
|
135
|
+
error.OutOfMemory => return .out_of_memory,
|
|
136
|
+
error.AddressInvalid => return .address_invalid,
|
|
137
|
+
error.AddressLimitExceeded => return .address_limit_exceeded,
|
|
138
|
+
error.PacketsCountInvalid => return .packets_count_invalid,
|
|
139
|
+
error.SystemResources => return .system_resources,
|
|
140
|
+
error.NetworkSubsystemFailed => return .network_subsystem,
|
|
141
|
+
};
|
|
142
|
+
|
|
143
|
+
out_client.* = context_to_client(&context.implementation);
|
|
144
|
+
var list = tb_packet_list_t{};
|
|
145
|
+
for (context.packets) |*packet| {
|
|
146
|
+
list.push(tb_packet_list_t.from(packet));
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
out_packets.* = list;
|
|
150
|
+
return .success;
|
|
151
|
+
}
|
|
152
|
+
|
|
88
153
|
pub export fn tb_client_submit(
|
|
89
154
|
client: tb_client_t,
|
|
90
155
|
packets: *tb_packet_list_t,
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
const std = @import("std");
|
|
2
|
+
const assert = std.debug.assert;
|
|
3
|
+
|
|
4
|
+
const tb = @import("../tigerbeetle.zig");
|
|
5
|
+
const tb_client = @import("./tb_client.zig");
|
|
6
|
+
const c = @cImport(@cInclude("tb_client.h"));
|
|
7
|
+
|
|
8
|
+
fn to_lowercase(comptime input: []const u8) []const u8 {
|
|
9
|
+
comptime var lowercase: [input.len]u8 = undefined;
|
|
10
|
+
inline for (input) |char, i| {
|
|
11
|
+
const is_uppercase = (char >= 'A') and (char <= 'Z');
|
|
12
|
+
lowercase[i] = char + (@as(u8, @boolToInt(is_uppercase)) * 32);
|
|
13
|
+
}
|
|
14
|
+
return &lowercase;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
fn to_uppercase(comptime input: []const u8) []const u8 {
|
|
18
|
+
comptime var uppercase: [input.len]u8 = undefined;
|
|
19
|
+
inline for (input) |char, i| {
|
|
20
|
+
const is_lowercase = (char >= 'a') and (char <= 'z');
|
|
21
|
+
uppercase[i] = char - (@as(u8, @boolToInt(is_lowercase)) * 32);
|
|
22
|
+
}
|
|
23
|
+
return &uppercase;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
fn to_snakecase(comptime input: []const u8) []const u8 {
|
|
27
|
+
comptime var output: []const u8 = &.{};
|
|
28
|
+
inline for (input) |char, i| {
|
|
29
|
+
const is_uppercase = (char >= 'A') and (char <= 'Z');
|
|
30
|
+
if (is_uppercase and i > 0) output = "_" ++ output;
|
|
31
|
+
output = output ++ &[_]u8{char};
|
|
32
|
+
}
|
|
33
|
+
return output;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
test "valid tb_client.h" {
|
|
37
|
+
@setEvalBranchQuota(10_000);
|
|
38
|
+
|
|
39
|
+
inline for (.{
|
|
40
|
+
.{ tb.Account, "tb_account_t" },
|
|
41
|
+
.{ tb.Transfer, "tb_transfer_t" },
|
|
42
|
+
.{ tb.AccountFlags, "TB_ACCOUNT_FLAGS" },
|
|
43
|
+
.{ tb.TransferFlags, "TB_TRANSFER_FLAGS" },
|
|
44
|
+
.{ tb.CreateAccountResult, "TB_CREATE_ACCOUNT_RESULT" },
|
|
45
|
+
.{ tb.CreateTransferResult, "TB_CREATE_TRANSFER_RESULT" },
|
|
46
|
+
.{ tb.CreateAccountsResult, "tb_create_accounts_result_t" },
|
|
47
|
+
.{ tb.CreateTransfersResult, "tb_create_transfers_result_t" },
|
|
48
|
+
|
|
49
|
+
.{ u128, "tb_uint128_t" },
|
|
50
|
+
.{ tb_client.tb_status_t, "TB_STATUS" },
|
|
51
|
+
.{ tb_client.tb_client_t, "tb_client_t" },
|
|
52
|
+
.{ tb_client.tb_packet_t, "tb_packet_t" },
|
|
53
|
+
.{ tb_client.tb_packet_list_t, "tb_packet_list_t" },
|
|
54
|
+
.{ tb_client.tb_packet_status_t, "TB_PACKET_STATUS" },
|
|
55
|
+
}) |c_export| {
|
|
56
|
+
const ty: type = c_export[0];
|
|
57
|
+
const c_type_name = @as([]const u8, c_export[1]);
|
|
58
|
+
const c_type: type = @field(c, c_type_name);
|
|
59
|
+
|
|
60
|
+
switch (@typeInfo(ty)) {
|
|
61
|
+
.Int => comptime assert(ty == c_type),
|
|
62
|
+
.Pointer => comptime assert(@sizeOf(ty) == @sizeOf(c_type)),
|
|
63
|
+
.Enum => {
|
|
64
|
+
const prefix_offset = comptime std.mem.lastIndexOf(u8, c_type_name, "_").?;
|
|
65
|
+
comptime var c_enum_prefix: []const u8 = c_type_name[0 .. prefix_offset + 1];
|
|
66
|
+
comptime assert(c_type == c_uint);
|
|
67
|
+
|
|
68
|
+
// TB_STATUS is a special case in naming
|
|
69
|
+
if (comptime std.mem.eql(u8, c_type_name, "TB_STATUS")) {
|
|
70
|
+
c_enum_prefix = c_type_name ++ "_";
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
// Compare the enum int values in C to the enum int values in Zig.
|
|
74
|
+
inline for (std.meta.fields(ty)) |field| {
|
|
75
|
+
const c_enum_field = comptime to_uppercase(to_snakecase(field.name));
|
|
76
|
+
const c_value = @field(c, c_enum_prefix ++ c_enum_field);
|
|
77
|
+
|
|
78
|
+
const zig_value = @enumToInt(@field(ty, field.name));
|
|
79
|
+
comptime assert(zig_value == c_value);
|
|
80
|
+
}
|
|
81
|
+
},
|
|
82
|
+
.Struct => |type_info| switch (type_info.layout) {
|
|
83
|
+
.Auto => @compileError("struct must be extern or packed to be used in C"),
|
|
84
|
+
.Packed => {
|
|
85
|
+
const prefix_offset = comptime std.mem.lastIndexOf(u8, c_type_name, "_").?;
|
|
86
|
+
const c_enum_prefix = c_type_name[0 .. prefix_offset + 1];
|
|
87
|
+
comptime assert(c_type == c_uint);
|
|
88
|
+
|
|
89
|
+
inline for (std.meta.fields(ty)) |field| {
|
|
90
|
+
if (comptime !std.mem.eql(u8, field.name, "padding")) {
|
|
91
|
+
// Get the bit value in the C enum.
|
|
92
|
+
const c_enum_field = comptime to_uppercase(to_snakecase(field.name));
|
|
93
|
+
const c_value = @field(c, c_enum_prefix ++ c_enum_field);
|
|
94
|
+
|
|
95
|
+
// Compare the bit value to the packed struct's field.
|
|
96
|
+
comptime var instance = std.mem.zeroes(ty);
|
|
97
|
+
@field(instance, field.name) = true;
|
|
98
|
+
comptime assert(@bitCast(u16, instance) == c_value);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
},
|
|
102
|
+
.Extern => {
|
|
103
|
+
// Ensure structs are effectively the same.
|
|
104
|
+
comptime assert(@sizeOf(ty) == @sizeOf(c_type));
|
|
105
|
+
comptime assert(@alignOf(ty) == @alignOf(c_type));
|
|
106
|
+
|
|
107
|
+
inline for (std.meta.fields(ty)) |field| {
|
|
108
|
+
// In C, packed structs and enums are replaced with integers.
|
|
109
|
+
comptime var field_type = field.field_type;
|
|
110
|
+
switch (@typeInfo(field_type)) {
|
|
111
|
+
.Struct => |info| {
|
|
112
|
+
comptime assert(info.layout == .Packed);
|
|
113
|
+
comptime assert(@sizeOf(field_type) <= @sizeOf(u128));
|
|
114
|
+
field_type = std.meta.Int(.unsigned, @bitSizeOf(field_type));
|
|
115
|
+
},
|
|
116
|
+
.Enum => |info| field_type = info.tag_type,
|
|
117
|
+
else => {},
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
// In C, pointers are opaque so we compare only the field sizes,
|
|
121
|
+
comptime var c_field_type = @TypeOf(@field(@as(c_type, undefined), field.name));
|
|
122
|
+
switch (@typeInfo(c_field_type)) {
|
|
123
|
+
.Pointer => |info| {
|
|
124
|
+
comptime assert(info.size == .C);
|
|
125
|
+
comptime assert(@sizeOf(c_field_type) == @sizeOf(field_type));
|
|
126
|
+
},
|
|
127
|
+
else => comptime assert(c_field_type == field_type),
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
},
|
|
131
|
+
},
|
|
132
|
+
else => |i| @compileLog("TODO", i),
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
}
|