@peerbit/native-backbone 0.1.2 → 0.1.3
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/dist/wasm/native_backbone.d.ts +64 -64
- package/dist/wasm/native_backbone.js +3 -0
- package/dist/wasm/native_backbone_bg.wasm +0 -0
- package/dist/wasm/native_backbone_bg.wasm.d.ts +64 -64
- package/package.json +1 -1
- package/src/append_tx/committed_latest.rs +390 -317
- package/src/append_tx/committed_no_next.rs +66 -64
- package/src/append_tx/facts.rs +213 -147
- package/src/append_tx/mod.rs +160 -58
- package/src/append_tx/storage.rs +52 -28
- package/src/coordinates.rs +135 -44
- package/src/documents.rs +340 -100
- package/src/error.rs +244 -0
- package/src/js_interop.rs +230 -90
- package/src/lib.rs +4 -0
- package/src/raw_receive.rs +182 -107
- package/src/shared_log_plan.rs +65 -23
- package/src/sync_send.rs +19 -3
- package/src/time.rs +14 -0
- package/src/wire_sync.rs +147 -36
package/src/raw_receive.rs
CHANGED
|
@@ -9,6 +9,7 @@ use peerbit_shared_log_rust::{EntryCoordinateCommit, GidLeaderPlan};
|
|
|
9
9
|
use std::collections::{HashMap, HashSet};
|
|
10
10
|
use wasm_bindgen::prelude::*;
|
|
11
11
|
|
|
12
|
+
use crate::error::BackboneError;
|
|
12
13
|
use crate::js_interop::{
|
|
13
14
|
bytes_vec_from_array, ensure_same_len, hash_number_u64, numbers_to_rows, strings_from_array,
|
|
14
15
|
strings_slice_to_array, strings_to_array,
|
|
@@ -101,7 +102,7 @@ fn prepared_raw_receive_selection_from_leader_plans(
|
|
|
101
102
|
leader_plans: &[GidLeaderPlan],
|
|
102
103
|
self_hash: &str,
|
|
103
104
|
used_leader_sample_plans: bool,
|
|
104
|
-
) -> Result<JsValue,
|
|
105
|
+
) -> Result<JsValue, BackboneError> {
|
|
105
106
|
if leader_plans.len() != groups.len() {
|
|
106
107
|
return Ok(JsValue::UNDEFINED);
|
|
107
108
|
}
|
|
@@ -130,7 +131,7 @@ fn prepared_raw_receive_selection_from_leader_plans(
|
|
|
130
131
|
let mut dropped_indexes = Vec::new();
|
|
131
132
|
for (original_index, retained) in retained_original_indexes.iter().enumerate() {
|
|
132
133
|
let original_index = u32::try_from(original_index)
|
|
133
|
-
.map_err(|_|
|
|
134
|
+
.map_err(|_| BackboneError::RawReceiveOriginalIndexOverflow)?;
|
|
134
135
|
if *retained {
|
|
135
136
|
retained_indexes.push(original_index);
|
|
136
137
|
} else {
|
|
@@ -148,7 +149,7 @@ fn prepared_raw_receive_selection_from_leader_plans(
|
|
|
148
149
|
selected_index_by_original[original_index] = Some(selected_index);
|
|
149
150
|
selected_index = selected_index
|
|
150
151
|
.checked_add(1)
|
|
151
|
-
.
|
|
152
|
+
.ok_or(BackboneError::RawReceiveSelectedIndexOverflow)?;
|
|
152
153
|
}
|
|
153
154
|
}
|
|
154
155
|
for (index, (group, leader_plan)) in groups.iter().zip(leader_plans).enumerate() {
|
|
@@ -236,10 +237,10 @@ fn prepared_raw_entry_v0_to_row(entry: &PreparedRawEntryV0, hash_number: Option<
|
|
|
236
237
|
impl NativePeerbitBackbone {
|
|
237
238
|
pub fn prepare_raw_receive_batch(&mut self, blocks: Array) -> Result<Array, JsValue> {
|
|
238
239
|
let profile_enabled = self.append_profile_enabled;
|
|
239
|
-
let input_started = profile_enabled.then(
|
|
240
|
+
let input_started = profile_enabled.then(crate::time::now_ms);
|
|
240
241
|
let blocks = bytes_vec_from_array(blocks)?;
|
|
241
242
|
if let Some(started) = input_started {
|
|
242
|
-
self.append_profile.raw_receive_input_copy_ms +=
|
|
243
|
+
self.append_profile.raw_receive_input_copy_ms += crate::time::now_ms() - started;
|
|
243
244
|
}
|
|
244
245
|
let prepared = self.prepare_raw_receive_entries(blocks, None, true)?;
|
|
245
246
|
let out = Array::new();
|
|
@@ -266,13 +267,13 @@ impl NativePeerbitBackbone {
|
|
|
266
267
|
|
|
267
268
|
pub fn prepare_raw_receive_columns_batch(&mut self, blocks: Array) -> Result<Array, JsValue> {
|
|
268
269
|
let profile_enabled = self.append_profile_enabled;
|
|
269
|
-
let input_started = profile_enabled.then(
|
|
270
|
+
let input_started = profile_enabled.then(crate::time::now_ms);
|
|
270
271
|
let blocks = bytes_vec_from_array(blocks)?;
|
|
271
272
|
if let Some(started) = input_started {
|
|
272
|
-
self.append_profile.raw_receive_input_copy_ms +=
|
|
273
|
+
self.append_profile.raw_receive_input_copy_ms += crate::time::now_ms() - started;
|
|
273
274
|
}
|
|
274
275
|
let prepared = self.prepare_raw_receive_entries(blocks, None, true)?;
|
|
275
|
-
self.prepare_raw_receive_columns_from_entries(prepared, true, true)
|
|
276
|
+
Ok(self.prepare_raw_receive_columns_from_entries(prepared, true, true)?)
|
|
276
277
|
}
|
|
277
278
|
|
|
278
279
|
pub fn prepare_raw_receive_unverified_columns_batch(
|
|
@@ -280,13 +281,13 @@ impl NativePeerbitBackbone {
|
|
|
280
281
|
blocks: Array,
|
|
281
282
|
) -> Result<Array, JsValue> {
|
|
282
283
|
let profile_enabled = self.append_profile_enabled;
|
|
283
|
-
let input_started = profile_enabled.then(
|
|
284
|
+
let input_started = profile_enabled.then(crate::time::now_ms);
|
|
284
285
|
let blocks = bytes_vec_from_array(blocks)?;
|
|
285
286
|
if let Some(started) = input_started {
|
|
286
|
-
self.append_profile.raw_receive_input_copy_ms +=
|
|
287
|
+
self.append_profile.raw_receive_input_copy_ms += crate::time::now_ms() - started;
|
|
287
288
|
}
|
|
288
289
|
let prepared = self.prepare_raw_receive_entries(blocks, None, false)?;
|
|
289
|
-
self.prepare_raw_receive_columns_from_entries(prepared, true, true)
|
|
290
|
+
Ok(self.prepare_raw_receive_columns_from_entries(prepared, true, true)?)
|
|
290
291
|
}
|
|
291
292
|
|
|
292
293
|
pub fn prepare_raw_receive_expected_columns_batch(
|
|
@@ -295,14 +296,14 @@ impl NativePeerbitBackbone {
|
|
|
295
296
|
hashes: Array,
|
|
296
297
|
) -> Result<Array, JsValue> {
|
|
297
298
|
let profile_enabled = self.append_profile_enabled;
|
|
298
|
-
let input_started = profile_enabled.then(
|
|
299
|
+
let input_started = profile_enabled.then(crate::time::now_ms);
|
|
299
300
|
let blocks = bytes_vec_from_array(blocks)?;
|
|
300
301
|
let hashes = strings_from_array(hashes)?;
|
|
301
302
|
if let Some(started) = input_started {
|
|
302
|
-
self.append_profile.raw_receive_input_copy_ms +=
|
|
303
|
+
self.append_profile.raw_receive_input_copy_ms += crate::time::now_ms() - started;
|
|
303
304
|
}
|
|
304
305
|
let prepared = self.prepare_raw_receive_entries(blocks, Some(hashes), true)?;
|
|
305
|
-
self.prepare_raw_receive_columns_from_entries(prepared, true, true)
|
|
306
|
+
Ok(self.prepare_raw_receive_columns_from_entries(prepared, true, true)?)
|
|
306
307
|
}
|
|
307
308
|
|
|
308
309
|
pub fn prepare_raw_receive_unverified_expected_columns_batch(
|
|
@@ -311,14 +312,14 @@ impl NativePeerbitBackbone {
|
|
|
311
312
|
hashes: Array,
|
|
312
313
|
) -> Result<Array, JsValue> {
|
|
313
314
|
let profile_enabled = self.append_profile_enabled;
|
|
314
|
-
let input_started = profile_enabled.then(
|
|
315
|
+
let input_started = profile_enabled.then(crate::time::now_ms);
|
|
315
316
|
let blocks = bytes_vec_from_array(blocks)?;
|
|
316
317
|
let hashes = strings_from_array(hashes)?;
|
|
317
318
|
if let Some(started) = input_started {
|
|
318
|
-
self.append_profile.raw_receive_input_copy_ms +=
|
|
319
|
+
self.append_profile.raw_receive_input_copy_ms += crate::time::now_ms() - started;
|
|
319
320
|
}
|
|
320
321
|
let prepared = self.prepare_raw_receive_entries(blocks, Some(hashes), false)?;
|
|
321
|
-
self.prepare_raw_receive_columns_from_entries(prepared, true, true)
|
|
322
|
+
Ok(self.prepare_raw_receive_columns_from_entries(prepared, true, true)?)
|
|
322
323
|
}
|
|
323
324
|
|
|
324
325
|
pub fn prepare_raw_receive_expected_compact_columns_batch(
|
|
@@ -327,14 +328,14 @@ impl NativePeerbitBackbone {
|
|
|
327
328
|
hashes: Array,
|
|
328
329
|
) -> Result<Array, JsValue> {
|
|
329
330
|
let profile_enabled = self.append_profile_enabled;
|
|
330
|
-
let input_started = profile_enabled.then(
|
|
331
|
+
let input_started = profile_enabled.then(crate::time::now_ms);
|
|
331
332
|
let blocks = bytes_vec_from_array(blocks)?;
|
|
332
333
|
let hashes = strings_from_array(hashes)?;
|
|
333
334
|
if let Some(started) = input_started {
|
|
334
|
-
self.append_profile.raw_receive_input_copy_ms +=
|
|
335
|
+
self.append_profile.raw_receive_input_copy_ms += crate::time::now_ms() - started;
|
|
335
336
|
}
|
|
336
337
|
let prepared = self.prepare_raw_receive_entries(blocks, Some(hashes), true)?;
|
|
337
|
-
self.prepare_raw_receive_columns_from_entries(prepared, false, false)
|
|
338
|
+
Ok(self.prepare_raw_receive_columns_from_entries(prepared, false, false)?)
|
|
338
339
|
}
|
|
339
340
|
|
|
340
341
|
pub fn prepare_raw_receive_unverified_expected_compact_columns_batch(
|
|
@@ -343,14 +344,14 @@ impl NativePeerbitBackbone {
|
|
|
343
344
|
hashes: Array,
|
|
344
345
|
) -> Result<Array, JsValue> {
|
|
345
346
|
let profile_enabled = self.append_profile_enabled;
|
|
346
|
-
let input_started = profile_enabled.then(
|
|
347
|
+
let input_started = profile_enabled.then(crate::time::now_ms);
|
|
347
348
|
let blocks = bytes_vec_from_array(blocks)?;
|
|
348
349
|
let hashes = strings_from_array(hashes)?;
|
|
349
350
|
if let Some(started) = input_started {
|
|
350
|
-
self.append_profile.raw_receive_input_copy_ms +=
|
|
351
|
+
self.append_profile.raw_receive_input_copy_ms += crate::time::now_ms() - started;
|
|
351
352
|
}
|
|
352
353
|
let prepared = self.prepare_raw_receive_entries(blocks, Some(hashes), false)?;
|
|
353
|
-
self.prepare_raw_receive_columns_from_entries(prepared, false, false)
|
|
354
|
+
Ok(self.prepare_raw_receive_columns_from_entries(prepared, false, false)?)
|
|
354
355
|
}
|
|
355
356
|
|
|
356
357
|
#[allow(clippy::too_many_arguments)]
|
|
@@ -371,11 +372,11 @@ impl NativePeerbitBackbone {
|
|
|
371
372
|
_from_hash: String,
|
|
372
373
|
) -> Result<JsValue, JsValue> {
|
|
373
374
|
let profile_enabled = self.append_profile_enabled;
|
|
374
|
-
let input_started = profile_enabled.then(
|
|
375
|
+
let input_started = profile_enabled.then(crate::time::now_ms);
|
|
375
376
|
let blocks = bytes_vec_from_array(blocks)?;
|
|
376
377
|
let hashes = strings_from_array(hashes)?;
|
|
377
378
|
if let Some(started) = input_started {
|
|
378
|
-
self.append_profile.raw_receive_input_copy_ms +=
|
|
379
|
+
self.append_profile.raw_receive_input_copy_ms += crate::time::now_ms() - started;
|
|
379
380
|
}
|
|
380
381
|
let prepared = self.prepare_raw_receive_entries(blocks, Some(hashes.clone()), false)?;
|
|
381
382
|
let columns = self.prepare_raw_receive_columns_from_entries(prepared, false, false)?;
|
|
@@ -611,7 +612,7 @@ impl NativePeerbitBackbone {
|
|
|
611
612
|
include_strict_full_replica: bool,
|
|
612
613
|
_from_hash: String,
|
|
613
614
|
) -> Result<JsValue, JsValue> {
|
|
614
|
-
self.plan_prepared_raw_receive_selection_core(
|
|
615
|
+
Ok(self.plan_prepared_raw_receive_selection_core(
|
|
615
616
|
strings_from_array(hashes)?,
|
|
616
617
|
min_replicas,
|
|
617
618
|
max_replicas,
|
|
@@ -623,7 +624,7 @@ impl NativePeerbitBackbone {
|
|
|
623
624
|
include_self,
|
|
624
625
|
full_replica_fallback,
|
|
625
626
|
include_strict_full_replica,
|
|
626
|
-
)
|
|
627
|
+
)?)
|
|
627
628
|
}
|
|
628
629
|
|
|
629
630
|
#[allow(clippy::too_many_arguments)]
|
|
@@ -757,7 +758,7 @@ impl NativePeerbitBackbone {
|
|
|
757
758
|
return Ok(JsValue::UNDEFINED);
|
|
758
759
|
}
|
|
759
760
|
|
|
760
|
-
prepared_raw_receive_selection_from_leader_plans(
|
|
761
|
+
Ok(prepared_raw_receive_selection_from_leader_plans(
|
|
761
762
|
&self.resolution,
|
|
762
763
|
&groups,
|
|
763
764
|
expected_hash_count,
|
|
@@ -765,7 +766,7 @@ impl NativePeerbitBackbone {
|
|
|
765
766
|
&leader_plans,
|
|
766
767
|
&self_hash,
|
|
767
768
|
false,
|
|
768
|
-
)
|
|
769
|
+
)?)
|
|
769
770
|
}
|
|
770
771
|
|
|
771
772
|
pub fn verify_prepared_raw_receive_entries(
|
|
@@ -802,7 +803,7 @@ impl NativePeerbitBackbone {
|
|
|
802
803
|
coordinate_assigned_to_range_boundaries,
|
|
803
804
|
coordinate_requested_replicas,
|
|
804
805
|
)?;
|
|
805
|
-
self.commit_prepared_raw_receive_batch_core(hashes, &heads, coordinate_commits)
|
|
806
|
+
Ok(self.commit_prepared_raw_receive_batch_core(hashes, &heads, coordinate_commits)?)
|
|
806
807
|
}
|
|
807
808
|
|
|
808
809
|
#[allow(clippy::too_many_arguments)]
|
|
@@ -830,7 +831,7 @@ impl NativePeerbitBackbone {
|
|
|
830
831
|
coordinate_assigned_to_range_boundaries,
|
|
831
832
|
coordinate_requested_replicas,
|
|
832
833
|
)?;
|
|
833
|
-
self.commit_prepared_raw_receive_batch_core(hashes, &heads, coordinate_commits)
|
|
834
|
+
Ok(self.commit_prepared_raw_receive_batch_core(hashes, &heads, coordinate_commits)?)
|
|
834
835
|
}
|
|
835
836
|
|
|
836
837
|
#[allow(clippy::too_many_arguments)]
|
|
@@ -856,7 +857,7 @@ impl NativePeerbitBackbone {
|
|
|
856
857
|
coordinate_assigned_to_range_boundaries,
|
|
857
858
|
coordinate_requested_replicas,
|
|
858
859
|
)?;
|
|
859
|
-
self.commit_prepared_raw_receive_join_batch_core(hashes, &heads, coordinate_commits)
|
|
860
|
+
Ok(self.commit_prepared_raw_receive_join_batch_core(hashes, &heads, coordinate_commits)?)
|
|
860
861
|
}
|
|
861
862
|
|
|
862
863
|
#[allow(clippy::too_many_arguments)]
|
|
@@ -884,7 +885,7 @@ impl NativePeerbitBackbone {
|
|
|
884
885
|
coordinate_assigned_to_range_boundaries,
|
|
885
886
|
coordinate_requested_replicas,
|
|
886
887
|
)?;
|
|
887
|
-
self.commit_prepared_raw_receive_join_batch_core(hashes, &heads, coordinate_commits)
|
|
888
|
+
Ok(self.commit_prepared_raw_receive_join_batch_core(hashes, &heads, coordinate_commits)?)
|
|
888
889
|
}
|
|
889
890
|
|
|
890
891
|
#[allow(clippy::too_many_arguments)]
|
|
@@ -912,12 +913,12 @@ impl NativePeerbitBackbone {
|
|
|
912
913
|
coordinate_assigned_to_range_boundaries,
|
|
913
914
|
coordinate_requested_replicas,
|
|
914
915
|
)?;
|
|
915
|
-
self.commit_verified_prepared_raw_receive_join_batch_core(
|
|
916
|
+
Ok(self.commit_verified_prepared_raw_receive_join_batch_core(
|
|
916
917
|
hashes,
|
|
917
918
|
&heads,
|
|
918
919
|
Some(verify_hashes),
|
|
919
920
|
coordinate_commits,
|
|
920
|
-
)
|
|
921
|
+
)?)
|
|
921
922
|
}
|
|
922
923
|
|
|
923
924
|
#[allow(clippy::too_many_arguments)]
|
|
@@ -947,12 +948,12 @@ impl NativePeerbitBackbone {
|
|
|
947
948
|
coordinate_assigned_to_range_boundaries,
|
|
948
949
|
coordinate_requested_replicas,
|
|
949
950
|
)?;
|
|
950
|
-
self.commit_verified_prepared_raw_receive_join_batch_core(
|
|
951
|
+
Ok(self.commit_verified_prepared_raw_receive_join_batch_core(
|
|
951
952
|
hashes,
|
|
952
953
|
&heads,
|
|
953
954
|
Some(verify_hashes),
|
|
954
955
|
coordinate_commits,
|
|
955
|
-
)
|
|
956
|
+
)?)
|
|
956
957
|
}
|
|
957
958
|
|
|
958
959
|
#[allow(clippy::too_many_arguments)]
|
|
@@ -978,12 +979,12 @@ impl NativePeerbitBackbone {
|
|
|
978
979
|
coordinate_assigned_to_range_boundaries,
|
|
979
980
|
coordinate_requested_replicas,
|
|
980
981
|
)?;
|
|
981
|
-
self.commit_verified_prepared_raw_receive_join_batch_core(
|
|
982
|
+
Ok(self.commit_verified_prepared_raw_receive_join_batch_core(
|
|
982
983
|
hashes,
|
|
983
984
|
&heads,
|
|
984
985
|
None,
|
|
985
986
|
coordinate_commits,
|
|
986
|
-
)
|
|
987
|
+
)?)
|
|
987
988
|
}
|
|
988
989
|
|
|
989
990
|
#[allow(clippy::too_many_arguments)]
|
|
@@ -1011,12 +1012,12 @@ impl NativePeerbitBackbone {
|
|
|
1011
1012
|
coordinate_assigned_to_range_boundaries,
|
|
1012
1013
|
coordinate_requested_replicas,
|
|
1013
1014
|
)?;
|
|
1014
|
-
self.commit_verified_prepared_raw_receive_join_batch_core(
|
|
1015
|
+
Ok(self.commit_verified_prepared_raw_receive_join_batch_core(
|
|
1015
1016
|
hashes,
|
|
1016
1017
|
&heads,
|
|
1017
1018
|
None,
|
|
1018
1019
|
coordinate_commits,
|
|
1019
|
-
)
|
|
1020
|
+
)?)
|
|
1020
1021
|
}
|
|
1021
1022
|
|
|
1022
1023
|
pub fn clear_prepared_raw_receive_entries(&mut self, hashes: Array) -> Result<usize, JsValue> {
|
|
@@ -1036,9 +1037,9 @@ impl NativePeerbitBackbone {
|
|
|
1036
1037
|
blocks: Vec<Vec<u8>>,
|
|
1037
1038
|
expected_cids: Option<Vec<String>>,
|
|
1038
1039
|
verify_signatures: bool,
|
|
1039
|
-
) -> Result<Vec<PreparedRawEntryV0>,
|
|
1040
|
+
) -> Result<Vec<PreparedRawEntryV0>, BackboneError> {
|
|
1040
1041
|
let profile_enabled = self.append_profile_enabled;
|
|
1041
|
-
let prepare_started = profile_enabled.then(
|
|
1042
|
+
let prepare_started = profile_enabled.then(crate::time::now_ms);
|
|
1042
1043
|
let mut raw_profile = profile_enabled.then(RawEntryV0PrepareProfile::default);
|
|
1043
1044
|
let prepared = prepare_raw_entry_v0_blocks_with_expected_cids_and_verify_profiled(
|
|
1044
1045
|
blocks,
|
|
@@ -1047,7 +1048,7 @@ impl NativePeerbitBackbone {
|
|
|
1047
1048
|
raw_profile.as_mut(),
|
|
1048
1049
|
)?;
|
|
1049
1050
|
if let Some(started) = prepare_started {
|
|
1050
|
-
self.append_profile.raw_receive_prepare_ms +=
|
|
1051
|
+
self.append_profile.raw_receive_prepare_ms += crate::time::now_ms() - started;
|
|
1051
1052
|
}
|
|
1052
1053
|
if let Some(raw_profile) = raw_profile {
|
|
1053
1054
|
self.append_profile.add_raw_prepare_profile(&raw_profile);
|
|
@@ -1060,9 +1061,9 @@ impl NativePeerbitBackbone {
|
|
|
1060
1061
|
prepared: Vec<PreparedRawEntryV0>,
|
|
1061
1062
|
include_hash_digest_bytes: bool,
|
|
1062
1063
|
include_cids: bool,
|
|
1063
|
-
) -> Result<Array,
|
|
1064
|
+
) -> Result<Array, BackboneError> {
|
|
1064
1065
|
let profile_enabled = self.append_profile_enabled;
|
|
1065
|
-
let columns_started = profile_enabled.then(
|
|
1066
|
+
let columns_started = profile_enabled.then(crate::time::now_ms);
|
|
1066
1067
|
let len = prepared.len();
|
|
1067
1068
|
let cids = Array::new();
|
|
1068
1069
|
let hash_digest_bytes = Array::new();
|
|
@@ -1137,7 +1138,7 @@ impl NativePeerbitBackbone {
|
|
|
1137
1138
|
out.push(&Uint32Array::from(requested_replicas.as_slice()));
|
|
1138
1139
|
out.push(&BigUint64Array::from(hash_numbers.as_slice()));
|
|
1139
1140
|
if let Some(started) = columns_started {
|
|
1140
|
-
self.append_profile.raw_receive_prepare_columns_ms +=
|
|
1141
|
+
self.append_profile.raw_receive_prepare_columns_ms += crate::time::now_ms() - started;
|
|
1141
1142
|
}
|
|
1142
1143
|
Ok(out)
|
|
1143
1144
|
}
|
|
@@ -1156,7 +1157,7 @@ impl NativePeerbitBackbone {
|
|
|
1156
1157
|
include_self: bool,
|
|
1157
1158
|
full_replica_fallback: bool,
|
|
1158
1159
|
include_strict_full_replica: bool,
|
|
1159
|
-
) -> Result<JsValue,
|
|
1160
|
+
) -> Result<JsValue, BackboneError> {
|
|
1160
1161
|
let expected_hash_count = hashes.len();
|
|
1161
1162
|
if expected_hash_count == 0 {
|
|
1162
1163
|
return Ok(JsValue::UNDEFINED);
|
|
@@ -1193,7 +1194,7 @@ impl NativePeerbitBackbone {
|
|
|
1193
1194
|
include_self: bool,
|
|
1194
1195
|
full_replica_fallback: bool,
|
|
1195
1196
|
include_strict_full_replica: bool,
|
|
1196
|
-
) -> Result<JsValue,
|
|
1197
|
+
) -> Result<JsValue, BackboneError> {
|
|
1197
1198
|
let expected_hash_count = hashes.len();
|
|
1198
1199
|
let mut planned_hash_count = 0usize;
|
|
1199
1200
|
let mut gids = Vec::with_capacity(groups.len());
|
|
@@ -1250,7 +1251,7 @@ impl NativePeerbitBackbone {
|
|
|
1250
1251
|
hashes: Vec<String>,
|
|
1251
1252
|
min_replicas: u32,
|
|
1252
1253
|
max_replicas: JsValue,
|
|
1253
|
-
) -> Result<Option<Vec<ResolvedPendingRawReceiveGroupPlan>>,
|
|
1254
|
+
) -> Result<Option<Vec<ResolvedPendingRawReceiveGroupPlan>>, BackboneError> {
|
|
1254
1255
|
if hashes.is_empty() {
|
|
1255
1256
|
return Ok(Some(Vec::new()));
|
|
1256
1257
|
}
|
|
@@ -1261,7 +1262,7 @@ impl NativePeerbitBackbone {
|
|
|
1261
1262
|
} else {
|
|
1262
1263
|
max_replicas
|
|
1263
1264
|
.as_f64()
|
|
1264
|
-
.
|
|
1265
|
+
.ok_or(BackboneError::MaxReplicasMustBeNumber)?
|
|
1265
1266
|
.max(0.0)
|
|
1266
1267
|
.min(u32::MAX as f64) as u32
|
|
1267
1268
|
};
|
|
@@ -1277,7 +1278,7 @@ impl NativePeerbitBackbone {
|
|
|
1277
1278
|
return Ok(None);
|
|
1278
1279
|
};
|
|
1279
1280
|
let input_index = u32::try_from(input_index)
|
|
1280
|
-
.map_err(|_|
|
|
1281
|
+
.map_err(|_| BackboneError::RawReceiveGroupIndexOverflow)?;
|
|
1281
1282
|
|
|
1282
1283
|
let group_index = if let Some(index) = group_indexes.get(&pending.entry.gid) {
|
|
1283
1284
|
*index
|
|
@@ -1345,7 +1346,7 @@ impl NativePeerbitBackbone {
|
|
|
1345
1346
|
fn verify_pending_raw_receive_entries(
|
|
1346
1347
|
&mut self,
|
|
1347
1348
|
hashes: &[String],
|
|
1348
|
-
) -> Result<Option<Vec<u8>>,
|
|
1349
|
+
) -> Result<Option<Vec<u8>>, BackboneError> {
|
|
1349
1350
|
if hashes.is_empty() {
|
|
1350
1351
|
return Ok(Some(Vec::new()));
|
|
1351
1352
|
}
|
|
@@ -1366,7 +1367,18 @@ impl NativePeerbitBackbone {
|
|
|
1366
1367
|
if entries.is_empty() {
|
|
1367
1368
|
Some(Vec::new())
|
|
1368
1369
|
} else {
|
|
1369
|
-
|
|
1370
|
+
// Deliberate, documented swallow. This returns Err only when
|
|
1371
|
+
// the signature slices are not parseable as Ed25519 — i.e. a
|
|
1372
|
+
// non-Ed25519 signature scheme or malformed bytes. That is the
|
|
1373
|
+
// load-bearing "native cannot natively verify these slices ->
|
|
1374
|
+
// defer to the caller's TS fallback" path: mapping the parse
|
|
1375
|
+
// error to None (and thence Ok(None) below) is correct for
|
|
1376
|
+
// mixed-scheme verification, so the bound LogError is
|
|
1377
|
+
// intentionally discarded rather than propagated.
|
|
1378
|
+
match verify_prepared_entry_v0_ed25519_storage_slices(&entries) {
|
|
1379
|
+
Ok(flags) => Some(flags),
|
|
1380
|
+
Err(_parse_error) => None,
|
|
1381
|
+
}
|
|
1370
1382
|
}
|
|
1371
1383
|
};
|
|
1372
1384
|
|
|
@@ -1374,9 +1386,7 @@ impl NativePeerbitBackbone {
|
|
|
1374
1386
|
return Ok(None);
|
|
1375
1387
|
};
|
|
1376
1388
|
if verified.len() != verify_positions.len() {
|
|
1377
|
-
return Err(
|
|
1378
|
-
"Expected equal prepared raw receive verify lengths",
|
|
1379
|
-
));
|
|
1389
|
+
return Err(BackboneError::MismatchedPreparedRawReceiveVerifyLengths);
|
|
1380
1390
|
}
|
|
1381
1391
|
for (index, flag) in verify_positions.iter().zip(verified.iter()) {
|
|
1382
1392
|
out[*index] = *flag;
|
|
@@ -1393,7 +1403,7 @@ impl NativePeerbitBackbone {
|
|
|
1393
1403
|
fn verify_pending_raw_receive_entries_all(
|
|
1394
1404
|
&mut self,
|
|
1395
1405
|
hashes: &[String],
|
|
1396
|
-
) -> Result<Option<bool>,
|
|
1406
|
+
) -> Result<Option<bool>, BackboneError> {
|
|
1397
1407
|
if hashes.is_empty() {
|
|
1398
1408
|
return Ok(Some(true));
|
|
1399
1409
|
}
|
|
@@ -1413,7 +1423,17 @@ impl NativePeerbitBackbone {
|
|
|
1413
1423
|
if entries.is_empty() {
|
|
1414
1424
|
Some(true)
|
|
1415
1425
|
} else {
|
|
1416
|
-
|
|
1426
|
+
// Deliberate, documented swallow (see the per-entry twin
|
|
1427
|
+
// verify_pending_raw_receive_entries above). Err here means the
|
|
1428
|
+
// signature slices are not parseable as Ed25519 — a non-Ed25519
|
|
1429
|
+
// scheme or malformed bytes — so native cannot natively verify
|
|
1430
|
+
// them and we defer to the caller's TS fallback by resolving to
|
|
1431
|
+
// None -> Ok(None). The bound LogError is intentionally
|
|
1432
|
+
// discarded to preserve that mixed-scheme fallback control flow.
|
|
1433
|
+
match verify_prepared_entry_v0_ed25519_storage_slices_all(&entries) {
|
|
1434
|
+
Ok(all_verified) => Some(all_verified),
|
|
1435
|
+
Err(_parse_error) => None,
|
|
1436
|
+
}
|
|
1417
1437
|
}
|
|
1418
1438
|
};
|
|
1419
1439
|
|
|
@@ -1436,53 +1456,53 @@ impl NativePeerbitBackbone {
|
|
|
1436
1456
|
hashes: Vec<String>,
|
|
1437
1457
|
heads: &Uint8Array,
|
|
1438
1458
|
coordinate_commits: Vec<EntryCoordinateCommit>,
|
|
1439
|
-
) -> Result<bool,
|
|
1459
|
+
) -> Result<bool, BackboneError> {
|
|
1440
1460
|
ensure_same_len(hashes.len(), heads.length() as usize, "raw receive heads")?;
|
|
1441
1461
|
let profile_enabled = self.append_profile_enabled;
|
|
1442
|
-
let pending_check_started = profile_enabled.then(
|
|
1462
|
+
let pending_check_started = profile_enabled.then(crate::time::now_ms);
|
|
1443
1463
|
let missing_pending = hashes
|
|
1444
1464
|
.iter()
|
|
1445
1465
|
.any(|hash| !self.pending_raw_receive_entries.contains_key(hash));
|
|
1446
1466
|
if let Some(started) = pending_check_started {
|
|
1447
|
-
self.append_profile.raw_receive_pending_check_ms +=
|
|
1467
|
+
self.append_profile.raw_receive_pending_check_ms += crate::time::now_ms() - started;
|
|
1448
1468
|
}
|
|
1449
1469
|
if missing_pending {
|
|
1450
1470
|
return Ok(false);
|
|
1451
1471
|
}
|
|
1452
1472
|
|
|
1453
|
-
let remove_started = profile_enabled.then(
|
|
1473
|
+
let remove_started = profile_enabled.then(crate::time::now_ms);
|
|
1454
1474
|
let mut block_entries = Vec::with_capacity(hashes.len());
|
|
1455
1475
|
let mut graph_entries = Vec::with_capacity(hashes.len());
|
|
1456
1476
|
for (index, hash) in hashes.into_iter().enumerate() {
|
|
1457
1477
|
let pending = self
|
|
1458
1478
|
.pending_raw_receive_entries
|
|
1459
1479
|
.remove(&hash)
|
|
1460
|
-
.
|
|
1480
|
+
.ok_or(BackboneError::MissingPreparedRawReceiveEntry)?;
|
|
1461
1481
|
block_entries.push((hash, pending.storage_bytes));
|
|
1462
1482
|
let mut graph_entry = pending.entry;
|
|
1463
1483
|
graph_entry.head = heads.get_index(index as u32) != 0;
|
|
1464
1484
|
graph_entries.push(graph_entry);
|
|
1465
1485
|
}
|
|
1466
1486
|
if let Some(started) = remove_started {
|
|
1467
|
-
self.append_profile.raw_receive_remove_ms +=
|
|
1487
|
+
self.append_profile.raw_receive_remove_ms += crate::time::now_ms() - started;
|
|
1468
1488
|
}
|
|
1469
1489
|
|
|
1470
|
-
let block_put_started = profile_enabled.then(
|
|
1490
|
+
let block_put_started = profile_enabled.then(crate::time::now_ms);
|
|
1471
1491
|
self.blocks.put_entries_core(block_entries);
|
|
1472
1492
|
if let Some(started) = block_put_started {
|
|
1473
|
-
self.append_profile.raw_receive_block_put_ms +=
|
|
1493
|
+
self.append_profile.raw_receive_block_put_ms += crate::time::now_ms() - started;
|
|
1474
1494
|
}
|
|
1475
|
-
let graph_put_started = profile_enabled.then(
|
|
1495
|
+
let graph_put_started = profile_enabled.then(crate::time::now_ms);
|
|
1476
1496
|
self.log.put_entries_core(graph_entries);
|
|
1477
1497
|
if let Some(started) = graph_put_started {
|
|
1478
|
-
self.append_profile.raw_receive_graph_put_ms +=
|
|
1498
|
+
self.append_profile.raw_receive_graph_put_ms += crate::time::now_ms() - started;
|
|
1479
1499
|
}
|
|
1480
1500
|
if !coordinate_commits.is_empty() {
|
|
1481
|
-
let coordinate_started = profile_enabled.then(
|
|
1501
|
+
let coordinate_started = profile_enabled.then(crate::time::now_ms);
|
|
1482
1502
|
self.commit_entry_coordinate_commits(coordinate_commits);
|
|
1483
1503
|
if let Some(started) = coordinate_started {
|
|
1484
1504
|
self.append_profile.raw_receive_coordinate_commit_ms +=
|
|
1485
|
-
|
|
1505
|
+
crate::time::now_ms() - started;
|
|
1486
1506
|
}
|
|
1487
1507
|
}
|
|
1488
1508
|
Ok(true)
|
|
@@ -1493,35 +1513,35 @@ impl NativePeerbitBackbone {
|
|
|
1493
1513
|
hashes: Vec<String>,
|
|
1494
1514
|
heads: &Uint8Array,
|
|
1495
1515
|
coordinate_commits: Vec<EntryCoordinateCommit>,
|
|
1496
|
-
) -> Result<bool,
|
|
1516
|
+
) -> Result<bool, BackboneError> {
|
|
1497
1517
|
ensure_same_len(hashes.len(), heads.length() as usize, "raw receive heads")?;
|
|
1498
1518
|
let profile_enabled = self.append_profile_enabled;
|
|
1499
|
-
let pending_check_started = profile_enabled.then(
|
|
1519
|
+
let pending_check_started = profile_enabled.then(crate::time::now_ms);
|
|
1500
1520
|
let missing_pending = hashes
|
|
1501
1521
|
.iter()
|
|
1502
1522
|
.any(|hash| !self.pending_raw_receive_entries.contains_key(hash));
|
|
1503
1523
|
if let Some(started) = pending_check_started {
|
|
1504
|
-
self.append_profile.raw_receive_pending_check_ms +=
|
|
1524
|
+
self.append_profile.raw_receive_pending_check_ms += crate::time::now_ms() - started;
|
|
1505
1525
|
}
|
|
1506
1526
|
if missing_pending {
|
|
1507
1527
|
return Ok(false);
|
|
1508
1528
|
}
|
|
1509
1529
|
|
|
1510
1530
|
{
|
|
1511
|
-
let join_plan_started = profile_enabled.then(
|
|
1531
|
+
let join_plan_started = profile_enabled.then(crate::time::now_ms);
|
|
1512
1532
|
let mut graph_entries = Vec::with_capacity(hashes.len());
|
|
1513
1533
|
for hash in &hashes {
|
|
1514
1534
|
let pending = self
|
|
1515
1535
|
.pending_raw_receive_entries
|
|
1516
1536
|
.get(hash)
|
|
1517
|
-
.
|
|
1537
|
+
.ok_or(BackboneError::MissingPreparedRawReceiveEntry)?;
|
|
1518
1538
|
graph_entries.push(&pending.entry);
|
|
1519
1539
|
}
|
|
1520
1540
|
let join_plans = self
|
|
1521
1541
|
.log
|
|
1522
1542
|
.plan_join_entry_refs_core(&graph_entries, false, true);
|
|
1523
1543
|
if let Some(started) = join_plan_started {
|
|
1524
|
-
self.append_profile.raw_receive_join_plan_ms +=
|
|
1544
|
+
self.append_profile.raw_receive_join_plan_ms += crate::time::now_ms() - started;
|
|
1525
1545
|
}
|
|
1526
1546
|
let mut batch_hashes: Option<HashSet<&str>> = None;
|
|
1527
1547
|
for plan in join_plans {
|
|
@@ -1542,39 +1562,39 @@ impl NativePeerbitBackbone {
|
|
|
1542
1562
|
}
|
|
1543
1563
|
}
|
|
1544
1564
|
|
|
1545
|
-
let remove_started = profile_enabled.then(
|
|
1565
|
+
let remove_started = profile_enabled.then(crate::time::now_ms);
|
|
1546
1566
|
let mut block_entries = Vec::with_capacity(hashes.len());
|
|
1547
1567
|
let mut graph_entries = Vec::with_capacity(hashes.len());
|
|
1548
1568
|
for (index, hash) in hashes.into_iter().enumerate() {
|
|
1549
1569
|
let pending = self
|
|
1550
1570
|
.pending_raw_receive_entries
|
|
1551
1571
|
.remove(&hash)
|
|
1552
|
-
.
|
|
1572
|
+
.ok_or(BackboneError::MissingPreparedRawReceiveEntry)?;
|
|
1553
1573
|
block_entries.push((hash, pending.storage_bytes));
|
|
1554
1574
|
let mut graph_entry = pending.entry;
|
|
1555
1575
|
graph_entry.head = heads.get_index(index as u32) != 0;
|
|
1556
1576
|
graph_entries.push(graph_entry);
|
|
1557
1577
|
}
|
|
1558
1578
|
if let Some(started) = remove_started {
|
|
1559
|
-
self.append_profile.raw_receive_remove_ms +=
|
|
1579
|
+
self.append_profile.raw_receive_remove_ms += crate::time::now_ms() - started;
|
|
1560
1580
|
}
|
|
1561
1581
|
|
|
1562
|
-
let block_put_started = profile_enabled.then(
|
|
1582
|
+
let block_put_started = profile_enabled.then(crate::time::now_ms);
|
|
1563
1583
|
self.blocks.put_entries_core(block_entries);
|
|
1564
1584
|
if let Some(started) = block_put_started {
|
|
1565
|
-
self.append_profile.raw_receive_block_put_ms +=
|
|
1585
|
+
self.append_profile.raw_receive_block_put_ms += crate::time::now_ms() - started;
|
|
1566
1586
|
}
|
|
1567
|
-
let graph_put_started = profile_enabled.then(
|
|
1587
|
+
let graph_put_started = profile_enabled.then(crate::time::now_ms);
|
|
1568
1588
|
self.log.put_join_batch_entries_core(graph_entries);
|
|
1569
1589
|
if let Some(started) = graph_put_started {
|
|
1570
|
-
self.append_profile.raw_receive_graph_put_ms +=
|
|
1590
|
+
self.append_profile.raw_receive_graph_put_ms += crate::time::now_ms() - started;
|
|
1571
1591
|
}
|
|
1572
1592
|
if !coordinate_commits.is_empty() {
|
|
1573
|
-
let coordinate_started = profile_enabled.then(
|
|
1593
|
+
let coordinate_started = profile_enabled.then(crate::time::now_ms);
|
|
1574
1594
|
self.commit_entry_coordinate_commits(coordinate_commits);
|
|
1575
1595
|
if let Some(started) = coordinate_started {
|
|
1576
1596
|
self.append_profile.raw_receive_coordinate_commit_ms +=
|
|
1577
|
-
|
|
1597
|
+
crate::time::now_ms() - started;
|
|
1578
1598
|
}
|
|
1579
1599
|
}
|
|
1580
1600
|
Ok(true)
|
|
@@ -1586,7 +1606,7 @@ impl NativePeerbitBackbone {
|
|
|
1586
1606
|
heads: &Uint8Array,
|
|
1587
1607
|
verify_hashes: Option<Vec<String>>,
|
|
1588
1608
|
coordinate_commits: Vec<EntryCoordinateCommit>,
|
|
1589
|
-
) -> Result<bool,
|
|
1609
|
+
) -> Result<bool, BackboneError> {
|
|
1590
1610
|
ensure_same_len(hashes.len(), heads.length() as usize, "raw receive heads")?;
|
|
1591
1611
|
let profile_enabled = self.append_profile_enabled;
|
|
1592
1612
|
let verify_hashes_cover_commit = match verify_hashes.as_ref() {
|
|
@@ -1600,41 +1620,47 @@ impl NativePeerbitBackbone {
|
|
|
1600
1620
|
}
|
|
1601
1621
|
};
|
|
1602
1622
|
if !verify_hashes_cover_commit {
|
|
1603
|
-
let pending_check_started = profile_enabled.then(
|
|
1623
|
+
let pending_check_started = profile_enabled.then(crate::time::now_ms);
|
|
1604
1624
|
let missing_pending = hashes
|
|
1605
1625
|
.iter()
|
|
1606
1626
|
.any(|hash| !self.pending_raw_receive_entries.contains_key(hash));
|
|
1607
1627
|
if let Some(started) = pending_check_started {
|
|
1608
|
-
self.append_profile.raw_receive_pending_check_ms +=
|
|
1628
|
+
self.append_profile.raw_receive_pending_check_ms += crate::time::now_ms() - started;
|
|
1609
1629
|
}
|
|
1610
1630
|
if missing_pending {
|
|
1611
1631
|
return Ok(false);
|
|
1612
1632
|
}
|
|
1613
1633
|
}
|
|
1614
|
-
let verify_started = profile_enabled.then(
|
|
1634
|
+
let verify_started = profile_enabled.then(crate::time::now_ms);
|
|
1615
1635
|
if verify_hashes_cover_commit {
|
|
1616
1636
|
let verify_hashes = verify_hashes.as_ref().unwrap_or(&hashes);
|
|
1617
1637
|
let Some(verified) = self.verify_pending_raw_receive_entries_all(verify_hashes)? else {
|
|
1618
1638
|
return Ok(false);
|
|
1619
1639
|
};
|
|
1620
1640
|
if let Some(started) = verify_started {
|
|
1621
|
-
self.append_profile.raw_receive_verify_ms +=
|
|
1641
|
+
self.append_profile.raw_receive_verify_ms += crate::time::now_ms() - started;
|
|
1622
1642
|
}
|
|
1623
1643
|
if !verified {
|
|
1624
1644
|
return Ok(false);
|
|
1625
1645
|
}
|
|
1626
1646
|
} else {
|
|
1627
|
-
|
|
1647
|
+
// Unreachable by construction: verify_hashes_cover_commit is `true`
|
|
1648
|
+
// whenever verify_hashes is None (the match arm above), so reaching
|
|
1649
|
+
// this !verify_hashes_cover_commit branch guarantees Some. The
|
|
1650
|
+
// former `.expect("partial verify hashes")` trapped the whole wasm
|
|
1651
|
+
// instance on a breach; return a typed error instead so a breach
|
|
1652
|
+
// surfaces as a normal thrown value rather than a process abort.
|
|
1653
|
+
let verify_hashes = verify_hashes.ok_or(BackboneError::MissingPartialVerifyHashes)?;
|
|
1628
1654
|
let Some(verified) = self.verify_pending_raw_receive_entries(&verify_hashes)? else {
|
|
1629
1655
|
return Ok(false);
|
|
1630
1656
|
};
|
|
1631
1657
|
if let Some(started) = verify_started {
|
|
1632
|
-
self.append_profile.raw_receive_verify_ms +=
|
|
1658
|
+
self.append_profile.raw_receive_verify_ms += crate::time::now_ms() - started;
|
|
1633
1659
|
}
|
|
1634
1660
|
if verified.iter().any(|flag| *flag == 0) {
|
|
1635
1661
|
return Ok(false);
|
|
1636
1662
|
}
|
|
1637
|
-
let verify_status_started = profile_enabled.then(
|
|
1663
|
+
let verify_status_started = profile_enabled.then(crate::time::now_ms);
|
|
1638
1664
|
let missing_verified = hashes.iter().any(|hash| {
|
|
1639
1665
|
self.pending_raw_receive_entries
|
|
1640
1666
|
.get(hash)
|
|
@@ -1642,7 +1668,7 @@ impl NativePeerbitBackbone {
|
|
|
1642
1668
|
.unwrap_or(true)
|
|
1643
1669
|
});
|
|
1644
1670
|
if let Some(started) = verify_status_started {
|
|
1645
|
-
self.append_profile.raw_receive_verify_status_ms +=
|
|
1671
|
+
self.append_profile.raw_receive_verify_status_ms += crate::time::now_ms() - started;
|
|
1646
1672
|
}
|
|
1647
1673
|
if missing_verified {
|
|
1648
1674
|
return Ok(false);
|
|
@@ -1650,20 +1676,20 @@ impl NativePeerbitBackbone {
|
|
|
1650
1676
|
}
|
|
1651
1677
|
|
|
1652
1678
|
{
|
|
1653
|
-
let join_plan_started = profile_enabled.then(
|
|
1679
|
+
let join_plan_started = profile_enabled.then(crate::time::now_ms);
|
|
1654
1680
|
let mut graph_entries = Vec::with_capacity(hashes.len());
|
|
1655
1681
|
for hash in &hashes {
|
|
1656
1682
|
let pending = self
|
|
1657
1683
|
.pending_raw_receive_entries
|
|
1658
1684
|
.get(hash)
|
|
1659
|
-
.
|
|
1685
|
+
.ok_or(BackboneError::MissingPreparedRawReceiveEntry)?;
|
|
1660
1686
|
graph_entries.push(&pending.entry);
|
|
1661
1687
|
}
|
|
1662
1688
|
let join_plans = self
|
|
1663
1689
|
.log
|
|
1664
1690
|
.plan_join_entry_refs_core(&graph_entries, false, true);
|
|
1665
1691
|
if let Some(started) = join_plan_started {
|
|
1666
|
-
self.append_profile.raw_receive_join_plan_ms +=
|
|
1692
|
+
self.append_profile.raw_receive_join_plan_ms += crate::time::now_ms() - started;
|
|
1667
1693
|
}
|
|
1668
1694
|
let mut batch_hashes: Option<HashSet<&str>> = None;
|
|
1669
1695
|
for plan in join_plans {
|
|
@@ -1684,41 +1710,90 @@ impl NativePeerbitBackbone {
|
|
|
1684
1710
|
}
|
|
1685
1711
|
}
|
|
1686
1712
|
|
|
1687
|
-
let remove_started = profile_enabled.then(
|
|
1713
|
+
let remove_started = profile_enabled.then(crate::time::now_ms);
|
|
1688
1714
|
let mut block_entries = Vec::with_capacity(hashes.len());
|
|
1689
1715
|
let mut graph_entries = Vec::with_capacity(hashes.len());
|
|
1690
1716
|
for (index, hash) in hashes.into_iter().enumerate() {
|
|
1691
1717
|
let pending = self
|
|
1692
1718
|
.pending_raw_receive_entries
|
|
1693
1719
|
.remove(&hash)
|
|
1694
|
-
.
|
|
1720
|
+
.ok_or(BackboneError::MissingPreparedRawReceiveEntry)?;
|
|
1695
1721
|
block_entries.push((hash, pending.storage_bytes));
|
|
1696
1722
|
let mut graph_entry = pending.entry;
|
|
1697
1723
|
graph_entry.head = heads.get_index(index as u32) != 0;
|
|
1698
1724
|
graph_entries.push(graph_entry);
|
|
1699
1725
|
}
|
|
1700
1726
|
if let Some(started) = remove_started {
|
|
1701
|
-
self.append_profile.raw_receive_remove_ms +=
|
|
1727
|
+
self.append_profile.raw_receive_remove_ms += crate::time::now_ms() - started;
|
|
1702
1728
|
}
|
|
1703
1729
|
|
|
1704
|
-
let block_put_started = profile_enabled.then(
|
|
1730
|
+
let block_put_started = profile_enabled.then(crate::time::now_ms);
|
|
1705
1731
|
self.blocks.put_entries_core(block_entries);
|
|
1706
1732
|
if let Some(started) = block_put_started {
|
|
1707
|
-
self.append_profile.raw_receive_block_put_ms +=
|
|
1733
|
+
self.append_profile.raw_receive_block_put_ms += crate::time::now_ms() - started;
|
|
1708
1734
|
}
|
|
1709
|
-
let graph_put_started = profile_enabled.then(
|
|
1735
|
+
let graph_put_started = profile_enabled.then(crate::time::now_ms);
|
|
1710
1736
|
self.log.put_join_batch_entries_core(graph_entries);
|
|
1711
1737
|
if let Some(started) = graph_put_started {
|
|
1712
|
-
self.append_profile.raw_receive_graph_put_ms +=
|
|
1738
|
+
self.append_profile.raw_receive_graph_put_ms += crate::time::now_ms() - started;
|
|
1713
1739
|
}
|
|
1714
1740
|
if !coordinate_commits.is_empty() {
|
|
1715
|
-
let coordinate_started = profile_enabled.then(
|
|
1741
|
+
let coordinate_started = profile_enabled.then(crate::time::now_ms);
|
|
1716
1742
|
self.commit_entry_coordinate_commits(coordinate_commits);
|
|
1717
1743
|
if let Some(started) = coordinate_started {
|
|
1718
1744
|
self.append_profile.raw_receive_coordinate_commit_ms +=
|
|
1719
|
-
|
|
1745
|
+
crate::time::now_ms() - started;
|
|
1720
1746
|
}
|
|
1721
1747
|
}
|
|
1722
1748
|
Ok(true)
|
|
1723
1749
|
}
|
|
1724
1750
|
}
|
|
1751
|
+
|
|
1752
|
+
#[cfg(test)]
|
|
1753
|
+
mod tests {
|
|
1754
|
+
use crate::error::BackboneError;
|
|
1755
|
+
|
|
1756
|
+
#[test]
|
|
1757
|
+
fn raw_receive_selection_variants_render_exact_messages() {
|
|
1758
|
+
for (error, message) in [
|
|
1759
|
+
(
|
|
1760
|
+
BackboneError::MaxReplicasMustBeNumber,
|
|
1761
|
+
"maxReplicas must be a number",
|
|
1762
|
+
),
|
|
1763
|
+
(
|
|
1764
|
+
BackboneError::RawReceiveOriginalIndexOverflow,
|
|
1765
|
+
"Raw receive original index overflow",
|
|
1766
|
+
),
|
|
1767
|
+
(
|
|
1768
|
+
BackboneError::RawReceiveSelectedIndexOverflow,
|
|
1769
|
+
"Raw receive selected index overflow",
|
|
1770
|
+
),
|
|
1771
|
+
(
|
|
1772
|
+
BackboneError::RawReceiveGroupIndexOverflow,
|
|
1773
|
+
"Raw receive group index overflow",
|
|
1774
|
+
),
|
|
1775
|
+
] {
|
|
1776
|
+
assert_eq!(error.to_string(), message);
|
|
1777
|
+
}
|
|
1778
|
+
}
|
|
1779
|
+
|
|
1780
|
+
#[test]
|
|
1781
|
+
fn raw_receive_verify_and_commit_variants_render_exact_messages() {
|
|
1782
|
+
for (error, message) in [
|
|
1783
|
+
(
|
|
1784
|
+
BackboneError::MissingPreparedRawReceiveEntry,
|
|
1785
|
+
"Missing prepared raw receive entry",
|
|
1786
|
+
),
|
|
1787
|
+
(
|
|
1788
|
+
BackboneError::MismatchedPreparedRawReceiveVerifyLengths,
|
|
1789
|
+
"Expected equal prepared raw receive verify lengths",
|
|
1790
|
+
),
|
|
1791
|
+
(
|
|
1792
|
+
BackboneError::MissingPartialVerifyHashes,
|
|
1793
|
+
"Missing partial verify hashes",
|
|
1794
|
+
),
|
|
1795
|
+
] {
|
|
1796
|
+
assert_eq!(error.to_string(), message);
|
|
1797
|
+
}
|
|
1798
|
+
}
|
|
1799
|
+
}
|