This repository has been archived by the owner on Aug 30, 2022. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 28
/
Copy pathxaynet_ffi.h
820 lines (770 loc) · 27.7 KB
/
xaynet_ffi.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
/* Generated with cbindgen:0.17.0 */
/* Warning, this file is autogenerated by cbindgen. Don't modify this manually. */
#include <stdarg.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdlib.h>
/**
* Return value upon success
*/
#define OK 0
/**
* NULL pointer argument
*/
#define ERR_NULLPTR 1
/**
* Invalid coordinator URL
*/
#define ERR_INVALID_URL 2
/**
* Invalid settings: coordinator URL is not set
*/
#define ERR_SETTINGS_URL 3
/**
* Invalid settings: signing keys are not set
*/
#define ERR_SETTINGS_KEYS 4
/**
* Invalid settings: scalar is out of bounds
*/
#define ERR_SETTINGS_SCALAR 5
/**
* Failed to set the local model: invalid model
*/
#define ERR_SETMODEL_MODEL 6
/**
* Failed to set the local model: invalid data type
*/
#define ERR_SETMODEL_DATATYPE 7
/**
* Failed to initialized the crypto library
*/
#define ERR_CRYPTO_INIT 8
/**
* Invalid secret signing key
*/
#define ERR_CRYPTO_SECRET_KEY 9
/**
* Invalid public signing key
*/
#define ERR_CRYPTO_PUBLIC_KEY 10
/**
* No global model is currently available
*/
#define GLOBALMODEL_NONE 11
/**
* Failed to get the global model: communication with the coordinator failed
*/
#define ERR_GLOBALMODEL_IO 12
/**
* Failed to get the global model: invalid data type
*/
#define ERR_GLOBALMODEL_DATATYPE 13
/**
* Failed to get the global model: invalid buffer length
*/
#define ERR_GLOBALMODEL_LEN 14
/**
* Failed to get the global model: invalid model
*/
#define ERR_GLOBALMODEL_CONVERT 15
/**
* The participant is not taking part in the sum or update task
*/
#define PARTICIPANT_TASK_NONE 1
/**
* The participant is not taking part in the sum task
*/
#define PARTICIPANT_TASK_SUM (1 << 1)
/**
* The participant is not taking part in the update task
*/
#define PARTICIPANT_TASK_UPDATE (1 << 2)
/**
* The participant is expected to set the model it trained
*/
#define PARTICIPANT_SHOULD_SET_MODEL (1 << 3)
/**
* The participant is expected to set the model it trained
*/
#define PARTICIPANT_MADE_PROGRESS (1 << 4)
/**
* A new global model is available
*/
#define PARTICIPANT_NEW_GLOBALMODEL (1 << 5)
/**
* The original primitive data type of the numerical values to be masked.
*/
enum ModelDataType {
/**
* Numbers of type f32.
*/
MODEL_DATA_TYPE_F32 = 0,
/**
* Numbers of type f64.
*/
MODEL_DATA_TYPE_F64 = 1,
/**
* Numbers of type i32.
*/
MODEL_DATA_TYPE_I32 = 2,
/**
* Numbers of type i64.
*/
MODEL_DATA_TYPE_I64 = 3,
};
typedef uint8_t ModelDataType;
/**
* A signing key pair
*/
typedef struct KeyPair KeyPair;
/**
* A participant. It embeds an internal state machine that executes the PET
* protocol. However, it is the caller's responsibility to drive this state machine by
* calling [`Participant::tick()`], and to take action when the participant state
* changes.
*/
typedef struct Participant Participant;
/**
* A participant settings
*/
typedef struct Settings Settings;
/**
* ByteBuffer is a struct that represents an array of bytes to be sent over the FFI boundaries.
* There are several cases when you might want to use this, but the primary one for us
* is for returning protobuf-encoded data to Swift and Java. The type is currently rather
* limited (implementing almost no functionality), however in the future it may be
* more expanded.
*
* ## Caveats
*
* Note that the order of the fields is `len` (an i64) then `data` (a `*mut u8`), getting
* this wrong on the other side of the FFI will cause memory corruption and crashes.
* `i64` is used for the length instead of `u64` and `usize` because JNA has interop
* issues with both these types.
*
* ### `Drop` is not implemented
*
* ByteBuffer does not implement Drop. This is intentional. Memory passed into it will
* be leaked if it is not explicitly destroyed by calling [`ByteBuffer::destroy`], or
* [`ByteBuffer::destroy_into_vec`]. This is for two reasons:
*
* 1. In the future, we may allow it to be used for data that is not managed by
* the Rust allocator\*, and `ByteBuffer` assuming it's okay to automatically
* deallocate this data with the Rust allocator.
*
* 2. Automatically running destructors in unsafe code is a
* [frequent footgun](https://without.boats/blog/two-memory-bugs-from-ringbahn/)
* (among many similar issues across many crates).
*
* Note that calling `destroy` manually is often not needed, as usually you should
* be passing these to the function defined by [`define_bytebuffer_destructor!`] from
* the other side of the FFI.
*
* Because this type is essentially *only* useful in unsafe or FFI code (and because
* the most common usage pattern does not require manually managing the memory), it
* does not implement `Drop`.
*
* \* Note: in the case of multiple Rust shared libraries loaded at the same time,
* there may be multiple instances of "the Rust allocator" (one per shared library),
* in which case we're referring to whichever instance is active for the code using
* the `ByteBuffer`. Note that this doesn't occur on all platforms or build
* configurations, but treating allocators in different shared libraries as fully
* independent is always safe.
*
* ## Layout/fields
*
* This struct's field are not `pub` (mostly so that we can soundly implement `Send`, but also so
* that we can verify rust users are constructing them appropriately), the fields, their types, and
* their order are *very much* a part of the public API of this type. Consumers on the other side
* of the FFI will need to know its layout.
*
* If this were a C struct, it would look like
*
* ```c,no_run
* struct ByteBuffer {
* // Note: This should never be negative, but values above
* // INT64_MAX / i64::MAX are not allowed.
* int64_t len;
* // Note: nullable!
* uint8_t *data;
* };
* ```
*
* In rust, there are two fields, in this order: `len: i64`, and `data: *mut u8`.
*
* For clarity, the fact that the data pointer is nullable means that `Option<ByteBuffer>` is not
* the same size as ByteBuffer, and additionally is not FFI-safe (the latter point is not
* currently guaranteed anyway as of the time of writing this comment).
*
* ### Description of fields
*
* `data` is a pointer to an array of `len` bytes. Note that data can be a null pointer and therefore
* should be checked.
*
* The bytes array is allocated on the heap and must be freed on it as well. Critically, if there
* are multiple rust shared libraries using being used in the same application, it *must be freed
* on the same heap that allocated it*, or you will corrupt both heaps.
*
* Typically, this object is managed on the other side of the FFI (on the "FFI consumer"), which
* means you must expose a function to release the resources of `data` which can be done easily
* using the [`define_bytebuffer_destructor!`] macro provided by this crate.
*/
typedef struct ByteBuffer {
int64_t len;
uint8_t *data;
} ByteBuffer;
/**
* `FfiStr<'a>` is a safe (`#[repr(transparent)]`) wrapper around a
* nul-terminated `*const c_char` (e.g. a C string). Conceptually, it is
* similar to [`std::ffi::CStr`], except that it may be used in the signatures
* of extern "C" functions.
*
* Functions accepting strings should use this instead of accepting a C string
* directly. This allows us to write those functions using safe code without
* allowing safe Rust to cause memory unsafety.
*
* A single function for constructing these from Rust ([`FfiStr::from_raw`])
* has been provided. Most of the time, this should not be necessary, and users
* should accept `FfiStr` in the parameter list directly.
*
* ## Caveats
*
* An effort has been made to make this struct hard to misuse, however it is
* still possible, if the `'static` lifetime is manually specified in the
* struct. E.g.
*
* ```rust,no_run
* # use ffi_support::FfiStr;
* // NEVER DO THIS
* #[no_mangle]
* extern "C" fn never_do_this(s: FfiStr<'static>) {
* // save `s` somewhere, and access it after this
* // function returns.
* }
* ```
*
* Instead, one of the following patterns should be used:
*
* ```
* # use ffi_support::FfiStr;
* #[no_mangle]
* extern "C" fn valid_use_1(s: FfiStr<'_>) {
* // Use of `s` after this function returns is impossible
* }
* // Alternative:
* #[no_mangle]
* extern "C" fn valid_use_2(s: FfiStr) {
* // Use of `s` after this function returns is impossible
* }
* ```
*/
typedef const char *FfiStr;
/**
* The model configuration of the model that is expected in [`xaynet_ffi_participant_set_model()`].
*
* [`xaynet_ffi_participant_set_model()`]: crate::ffi::xaynet_ffi_participant_set_model
*/
typedef struct LocalModelConfig {
/**
* The expected data type of the model.
*/
ModelDataType data_type;
/**
* the expected length of the model.
*/
uint64_t len;
} LocalModelConfig;
/**
* Destroy the given `ByteBuffer` and free its memory. This function must only be
* called on `ByteBuffer`s that have been created on the Rust side of the FFI. If you
* have created a `ByteBuffer` on the other side of the FFI, do not use this function,
* use `free()` instead.
*
* # Return value
*
* - [`OK`] on success
* - [`ERR_NULLPTR`] if `buf` is NULL
*
* # Safety
*
* 1. When calling this method, you have to ensure that *either* the pointer is NULL
* *or* all of the following is true:
* - The pointer must be properly [aligned].
* - It must be "dereferencable" in the sense defined in the [`std::ptr`] module
* documentation.
* 2. After destroying the `ByteBuffer` the pointer becomes invalid and must not be
* used.
* 3. Calling this function on a `ByteBuffer` that has not been created on the Rust
* side of the FFI is UB.
*
* [`std::ptr`]: https://doc.rust-lang.org/std/ptr/index.html#safety
* [aligned]: https://doc.rust-lang.org/std/ptr/index.html#alignment
*/
int xaynet_ffi_byte_buffer_destroy(const struct ByteBuffer *buf);
/**
* Initialize the crypto library. This method must be called before instantiating a
* participant with [`xaynet_ffi_participant_new()`] or before generating new keys with
* [`xaynet_ffi_generate_key_pair()`].
*
* # Return value
*
* - [`OK`] if the initialization succeeded
* - -[`ERR_CRYPTO_INIT`] if the initialization failed
*
* # Safety
*
* This function is safe to call
*/
int xaynet_ffi_crypto_init(void);
/**
* Destroy the participant created by [`xaynet_ffi_participant_new()`] or
* [`xaynet_ffi_participant_restore()`].
*
* # Return value
*
* - [`OK`] on success
* - [`ERR_NULLPTR`] if `participant` is NULL
*
* # Safety
*
* 1. When calling this method, you have to ensure that *either* the pointer is NULL
* *or* all of the following is true:
* - The pointer must be properly [aligned].
* - It must be "dereferencable" in the sense defined in the [`std::ptr`] module
* documentation.
* 2. After destroying the `Participant`, the pointer becomes invalid and must not be
* used.
* 3. This function should only be called on a pointer that has been created by
* [`xaynet_ffi_participant_new()`] or [`xaynet_ffi_participant_restore()`]
*
* [`std::ptr`]: https://doc.rust-lang.org/std/ptr/index.html#safety
* [aligned]: https://doc.rust-lang.org/std/ptr/index.html#alignment
*/
int xaynet_ffi_participant_destroy(struct Participant *participant);
/**
* Instantiate a new participant with the given settings. The participant must be
* destroyed with [`xaynet_ffi_participant_destroy`].
*
* # Return value
*
* - a NULL pointer if `settings` is NULL or if the participant creation failed
* - a valid pointer to a [`Participant`] otherwise
*
* # Safety
*
* When calling this method, you have to ensure that *either* the pointer is NULL *or*
* all of the following is true:
*
* - The pointer must be properly [aligned].
* - It must be "dereferencable" in the sense defined in the [`std::ptr`] module
* documentation.
*
* After destroying the participant with [`xaynet_ffi_participant_destroy`] becomes
* invalid and must not be used.
*
* [`std::ptr`]: https://doc.rust-lang.org/std/ptr/index.html#safety
* [aligned]: https://doc.rust-lang.org/std/ptr/index.html#alignment
*/
struct Participant *xaynet_ffi_participant_new(const struct Settings *settings);
/**
* Drive the participant internal state machine. Every tick, the state machine
* attempts to perform a small work unit.
*
* # Return value
*
* - [`ERR_NULLPTR`] is `participant` is NULL
* - a bitflag otherwise, with the following flags:
* - [`PARTICIPANT_MADE_PROGRESS`]: if set, this flag indicates that the participant
* internal state machine was able to make some progress, and that the participant
* state changed. This information can be used as an indication for saving the
* participant state for instance. If the flag is not set, the state machine was
* not able to make progress. There are many potential causes for this, including:
* - the participant is not taking part to the current training round and is just
* waiting for a new one to start
* - the Xaynet coordinator is not reachable or has not published some
* information the participant is waiting for
* - the state machine is waiting for the model to be set (see
* [`xaynet_ffi_participant_set_model()`])
* - [`PARTICIPANT_TASK_NONE`], [`PARTICIPANT_TASK_SUM`] and
* [`PARTICIPANT_TASK_UPDATE`]: these flags are mutually exclusive, and indicate
* which task the participant has been selected for, for the current round. If
* [`PARTICIPANT_TASK_NONE`] is set, then the participant will just wait for a new
* round to start. If [`PARTICIPANT_TASK_UPDATE`] is set, then the participant has
* been selected to update the global model, and should prepare to provide a new
* model once the [`PARTICIPANT_SHOULD_SET_MODEL`] flag is set.
* - [`PARTICIPANT_SHOULD_SET_MODEL`]: if set, then the participant should set its
* model, by calling [`xaynet_ffi_participant_set_model()`]
* - [`PARTICIPANT_NEW_GLOBALMODEL`]: if set, the participant can fetch the new global
* model, by calling [`xaynet_ffi_participant_global_model()`]
*
* # Safety
*
* When calling this method, you have to ensure that *either* the pointer is NULL *or*
* all of the following is true:
*
* - The pointer must be properly [aligned].
* - It must be "dereferencable" in the sense defined in the [`std::ptr`] module
* documentation.
*
* After destroying the participant with [`xaynet_ffi_participant_destroy`] becomes
* invalid and must not be used.
*
* [`std::ptr`]: https://doc.rust-lang.org/std/ptr/index.html#safety
* [aligned]: https://doc.rust-lang.org/std/ptr/index.html#alignment
*/
int xaynet_ffi_participant_tick(struct Participant *participant);
/**
* Serialize the participant state and return a buffer that contains the serialized
* participant.
*
* # Safety
*
* 1. When calling this method, you have to ensure that *either* the pointer is NULL
* *or* all of the following is true:
* - The pointer must be properly [aligned].
* - It must be "dereferencable" in the sense defined in the [`std::ptr`] module
* documentation.
* 2. the `ByteBuffer` created by this function must be destroyed with
* [`xaynet_ffi_participant_destroy`]. Attempting to free the memory from the other
* side of the FFI is UB.
* 3. This function destroys the participant. Therefore, **the pointer becomes invalid
* and must not be used anymore**. Instead, a new participant should be created,
* either with [`xaynet_ffi_participant_new()`] or
* [`xaynet_ffi_participant_restore()`]
*
* [`std::ptr`]: https://doc.rust-lang.org/std/ptr/index.html#safety
* [aligned]: https://doc.rust-lang.org/std/ptr/index.html#alignment
*
* # Example
*
* To save the participant into a file:
*
* ```c
* const ByteBuffer *save_buf = xaynet_ffi_participant_save(participant);
* assert(save_buf);
*
* char *path = "./participant.bin";
* FILE *f = fopen(path, "w");
* fwrite(save_buf->data, 1, save_buf->len, f);
* fclose(f);
* ```
*/
const struct ByteBuffer *xaynet_ffi_participant_save(struct Participant *participant);
/**
* Restore the participant from a buffer that contained its serialized state.
*
* # Return value
*
* - a NULL pointer on failure
* - a pointer to the restored participant on success
*
* # Safety
*
* When calling this method, you have to ensure that *either* the pointers are NULL
* *or* all of the following is true:
* - The pointers must be properly [aligned].
* - They must be "dereferencable" in the sense defined in the [`std::ptr`] module
* documentation.
*
* [`std::ptr`]: https://doc.rust-lang.org/std/ptr/index.html#safety
* [aligned]: https://doc.rust-lang.org/std/ptr/index.html#alignment
*
* # Example
*
* To restore a participant from a file:
*
* ```c
* f = fopen("./participant.bin", "r");
* fseek(f, 0L, SEEK_END);
* int fsize = ftell(f);
* fseek(f, 0L, SEEK_SET);
* ByteBuffer buf = {
* .len = fsize,
* .data = (uint8_t *)malloc(fsize),
* };
* int n_read = fread(buf.data, 1, fsize, f);
* assert(n_read == fsize);
* fclose(f);
* Participant *restored =
* xaynet_ffi_participant_restore("http://localhost:8081", &buf);
* free(buf.data);
* ```
*/
struct Participant *xaynet_ffi_participant_restore(FfiStr url, const struct ByteBuffer *buffer);
/**
* Set the participant's model. Usually this should be called when the value returned
* by [`xaynet_ffi_participant_tick()`] contains the [`PARTICIPANT_SHOULD_SET_MODEL`]
* flag, but it can be called anytime. The model just won't be sent to the coordinator
* until it's time.
*
* - `buffer` should be a pointer to a buffer that contains the model
* - `data_type` specifies the type of the model weights (see [`DataType`]). The C header
* file generated by this crate provides an enum corresponding to the parameters: `DataType`.
* - `len` is the number of weights the model has
*
* # Return value
*
* - [`OK`] if the model is set successfully
* - [`ERR_NULLPTR`] if `participant` is NULL
* - [`ERR_SETMODEL_DATATYPE`] if the datatype is invalid
* - [`ERR_SETMODEL_MODEL`] if the model is invalid
*
* # Safety
*
* 1. When calling this method, you have to ensure that *either* the pointer is NULL
* *or* all of the following is true:
* - The pointer must be properly [aligned].
* - It must be "dereferencable" in the sense defined in the [`std::ptr`] module
* documentation.
* 2. If `len` or `data_type` do not match the model in `buffer`, this method will
* result in a buffer over-read.
*
* [`std::ptr`]: https://doc.rust-lang.org/std/ptr/index.html#safety
* [aligned]: https://doc.rust-lang.org/std/ptr/index.html#alignment
*/
int xaynet_ffi_participant_set_model(struct Participant *participant,
const void *buffer,
unsigned char data_type,
unsigned int len);
/**
* Return the latest global model from the coordinator.
*
* - `buffer` is the array in which the global model should be copied.
* - `data_type` specifies the type of the model weights (see [`DataType`]). The C header
* file generated by this crate provides an enum corresponding to the parameters: `DataType`.
* - `len` is the number of weights the model has
*
* # Return Value
*
* - [`OK`] if the model is set successfully
* - [`ERR_NULLPTR`] if `participant` or the `buffer` is NULL
* - [`GLOBALMODEL_NONE`] if no model exists
* - [`ERR_GLOBALMODEL_IO`] if the communication with the coordinator failed
* - [`ERR_GLOBALMODEL_DATATYPE`] if the datatype is invalid
* - [`ERR_GLOBALMODEL_LEN`] if the length of the buffer does not match the length of the model
* - [`ERR_GLOBALMODEL_CONVERT`] if the conversion of the model failed
*
* # Note
*
* It is **not** guaranteed, that the model configuration returned by
* [`xaynet_ffi_participant_local_model_config`] corresponds to the configuration of
* the global model. This means that the global model can have a different length / data type
* than it is defined in model configuration. That both model configurations are the same is
* only guaranteed if the model config **never** changes on the coordinator side.
*
* # Safety
*
* 1. When calling this method, you have to ensure that *either* the pointer is NULL
* *or* all of the following is true:
* - The pointer must be properly [aligned].
* - It must be "dereferencable" in the sense defined in the [`std::ptr`] module
* documentation.
* 2. If `len` or `data_type` do not match the model in `buffer`, this method will
* result in a buffer over-read.
*
* [aligned]: https://doc.rust-lang.org/std/ptr/index.html#alignment
*/
int xaynet_ffi_participant_global_model(struct Participant *participant,
void *buffer,
unsigned char data_type,
unsigned int len);
/**
* Return the local model configuration of the model that is expected in the
* [`xaynet_ffi_participant_set_model()`] function.
*
* # Safety
*
* 1. When calling this method, you have to ensure that *either* the pointer is NULL
* *or* all of the following is true:
* - The pointer must be properly [aligned].
* - It must be "dereferencable" in the sense defined in the [`std::ptr`] module
* documentation.
*
* [aligned]: https://doc.rust-lang.org/std/ptr/index.html#alignment
*/
struct LocalModelConfig *xaynet_ffi_participant_local_model_config(const struct Participant *participant);
/**
* Destroy the settings created by [`xaynet_ffi_settings_new()`].
*
* # Return value
*
* - [`OK`] on success
* - [`ERR_NULLPTR`] if `buf` is NULL
*
* # Safety
*
* 1. When calling this method, you have to ensure that *either* the pointer is NULL
* *or* all of the following is true:
* - The pointer must be properly [aligned].
* - It must be "dereferencable" in the sense defined in the [`std::ptr`] module
* documentation.
* 2. After destroying the `Settings`, the pointer becomes invalid and must not be
* used.
* 3. This function should only be called on a pointer that has been created by
* [`xaynet_ffi_settings_new`].
*
* [`std::ptr`]: https://doc.rust-lang.org/std/ptr/index.html#safety
* [aligned]: https://doc.rust-lang.org/std/ptr/index.html#alignment
*/
int xaynet_ffi_settings_destroy(struct Settings *settings);
/**
* Create new [`Settings`] and return a pointer to it.
*
* # Safety
*
* The `Settings` created by this function must be destroyed with
* [`xaynet_ffi_settings_destroy()`]. Attempting to free the memory from the other side
* of the FFI is UB.
*/
struct Settings *xaynet_ffi_settings_new(void);
/**
* Set scalar setting.
*
* # Return value
*
* - [`OK`] if successful
* - [`ERR_NULLPTR`] if `settings` is `NULL`
*
* # Safety
*
* When calling this method, you have to ensure that *either* the pointer is NULL *or*
* all of the following is true:
* - The pointer must be properly [aligned].
* - It must be "dereferencable" in the sense defined in the [`std::ptr`] module
* documentation.
*
* [`std::ptr`]: https://doc.rust-lang.org/std/ptr/index.html#safety
* [aligned]: https://doc.rust-lang.org/std/ptr/index.html#alignment
*/
int xaynet_ffi_settings_set_scalar(struct Settings *settings, double scalar);
/**
* Set coordinator URL.
*
* # Return value
*
* - [`OK`] if successful
* - [`ERR_INVALID_URL`] if `url` is not a valid string
* - [`ERR_NULLPTR`] if `settings` is `NULL`
*
* # Safety
*
* When calling this method, you have to ensure that *either* the pointers are NULL
* *or* all of the following is true:
* - The pointers must be properly [aligned].
* - They must be "dereferencable" in the sense defined in the [`std::ptr`] module
* documentation.
*
* [`std::ptr`]: https://doc.rust-lang.org/std/ptr/index.html#safety
* [aligned]: https://doc.rust-lang.org/std/ptr/index.html#alignment
*/
int xaynet_ffi_settings_set_url(struct Settings *settings, FfiStr url);
/**
* Generate a new signing key pair that can be used in the [`Settings`]. **Before
* calling this function you must initialize the crypto library with
* [`xaynet_ffi_crypto_init()`]**.
*
* The returned value contains a pointer to the secret key. For security reasons, you
* must make sure that this buffer life is a short as possible, and call
* [`xaynet_ffi_forget_key_pair`] to destroy it.
*
* [`xaynet_ffi_crypto_init()`]: crate::ffi::xaynet_ffi_crypto_init
*
* # Safety
*
* This function is safe to call
*/
const struct KeyPair *xaynet_ffi_generate_key_pair(void);
/**
* De-allocate the buffers that contain the signing keys, and zero out the content of
* the buffer that contains the secret key.
*
* # Return value
*
* - [`ERR_NULLPTR`] is `key_pair` is NULL
* - [`OK`] otherwise
*
* # Safety
*
* When calling this method, you have to ensure that *either* the pointer is NULL *or*
* all of the following is true:
* - The pointer must be properly [aligned].
* - It must be "dereferencable" in the sense defined in the [`std::ptr`] module
* documentation.
*
* [`std::ptr`]: https://doc.rust-lang.org/std/ptr/index.html#safety
* [aligned]: https://doc.rust-lang.org/std/ptr/index.html#alignment
*/
int xaynet_ffi_forget_key_pair(const struct KeyPair *key_pair);
/**
* Set participant signing keys.
*
* # Return value
*
* - [`OK`] if successful
* - [`ERR_NULLPTR`] if `settings` or `key_pair` is `NULL`
* - [`ERR_CRYPTO_PUBLIC_KEY`] if the given `key_pair` contains an invalid public key
* - [`ERR_CRYPTO_SECRET_KEY`] if the given `key_pair` contains an invalid secret key
*
* # Safety
*
* When calling this method, you have to ensure that *either* the pointers are NULL
* *or* all of the following is true:
* - The pointers must be properly [aligned].
* - They must be "dereferencable" in the sense defined in the [`std::ptr`] module
* documentation.
*
* [`std::ptr`]: https://doc.rust-lang.org/std/ptr/index.html#safety
* [aligned]: https://doc.rust-lang.org/std/ptr/index.html#alignment
*/
int xaynet_ffi_settings_set_keys(struct Settings *settings, const struct KeyPair *key_pair);
/**
* Check whether the given settings are valid and can be used to instantiate a
* participant (see [`xaynet_ffi_participant_new()`]).
*
* # Return value
*
* - [`OK`] on success
* - [`ERR_SETTINGS_URL`] if the URL has not been set
* - [`ERR_SETTINGS_KEYS`] if the signing keys have not been set
* - [`ERR_SETTINGS_SCALAR`] if the scalar is out of bounds
*
* # Safety
*
* When calling this method, you have to ensure that *either* the pointer is NULL *or*
* all of the following is true:
*
* - The pointer must be properly [aligned].
* - It must be "dereferencable" in the sense defined in the [`std::ptr`] module
* documentation.
*
* [`xaynet_ffi_participant_new()`]: crate::ffi::xaynet_ffi_participant_new
* [`std::ptr`]: https://doc.rust-lang.org/std/ptr/index.html#safety
* [aligned]: https://doc.rust-lang.org/std/ptr/index.html#alignment
*/
int xaynet_ffi_check_settings(const struct Settings *settings);
/**
* Destroy the model configuration created by [`xaynet_ffi_participant_local_model_config()`].
*
* # Return value
*
* - [`OK`] on success
* - [`ERR_NULLPTR`] if `local_model_config` is NULL
*
* # Safety
*
* 1. When calling this method, you have to ensure that *either* the pointer is NULL
* *or* all of the following is true:
* - The pointer must be properly [aligned].
* - It must be "dereferencable" in the sense defined in the [`std::ptr`] module
* documentation.
* 2. After destroying the `LocalModelConfig`, the pointer becomes invalid and must not be
* used.
* 3. This function should only be called on a pointer that has been created by
* [`xaynet_ffi_participant_local_model_config()`].
*
* [`std::ptr`]: https://doc.rust-lang.org/std/ptr/index.html#safety
* [aligned]: https://doc.rust-lang.org/std/ptr/index.html#alignment
* [`xaynet_ffi_participant_local_model_config()`]: crate::ffi::xaynet_ffi_participant_local_model_config
*/
int xaynet_ffi_local_model_config_destroy(struct LocalModelConfig *local_model_config);