@feltdb/core 0.4.12 → 0.4.14
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/cli/commands.js +42 -25
- package/dist/cli/index.js +1 -1
- package/dist/create/cli.js +39 -4
- package/dist/create/create.js +30 -18
- package/dist/create/docker-compose-generator.js +68 -11
- package/dist/create/package-versions.js +1 -1
- package/dist/create/server-source/Cargo.lock +2238 -0
- package/dist/create/server-source/Cargo.toml +7 -0
- package/dist/create/server-source/crates/feltdb/Cargo.lock +175 -0
- package/dist/create/server-source/crates/feltdb/Cargo.toml +79 -0
- package/dist/create/server-source/crates/feltdb/benches/baselines/gate-13-redux.json +370 -0
- package/dist/create/server-source/crates/feltdb/benches/gate13_baseline.rs +589 -0
- package/dist/create/server-source/crates/feltdb/benches/gate13_phase_7_1_release_economics.rs +259 -0
- package/dist/create/server-source/crates/feltdb/benches/gate_13_redux.rs +446 -0
- package/dist/create/server-source/crates/feltdb/benches/gate_13_regression_runner.rs +272 -0
- package/dist/create/server-source/crates/feltdb/benches/gate_14a_concurrent_writer_scaling.rs +378 -0
- package/dist/create/server-source/crates/feltdb/benches/gate_14a_production_admission_revalidation.rs +414 -0
- package/dist/create/server-source/crates/feltdb/benches/gate_14a_rc2_admission_contract.rs +486 -0
- package/dist/create/server-source/crates/feltdb/benches/gate_14a_rc_root_cause.rs +273 -0
- package/dist/create/server-source/crates/feltdb/benches/gate_14a_sync1_queued_prototype.rs +587 -0
- package/dist/create/server-source/crates/feltdb/benches/gate_14a_sync_economics.rs +513 -0
- package/dist/create/server-source/crates/feltdb/benches/gate_14b_causal_backlog_scaling.rs +395 -0
- package/dist/create/server-source/crates/feltdb/benches/gate_14c_replication_contract_test.rs +469 -0
- package/dist/create/server-source/crates/feltdb/benches/gate_14c_replication_scaling.rs +409 -0
- package/dist/create/server-source/crates/feltdb/benches/gate_14d_combined_dimension_scaling.rs +627 -0
- package/dist/create/server-source/crates/feltdb/benches/phase_7_1_2_optimization_benchmark.rs +383 -0
- package/dist/create/server-source/crates/feltdb/benches/phase_7_1_3_crossover_analysis.rs +298 -0
- package/dist/create/server-source/crates/feltdb/src/acceptance_tests.rs +1698 -0
- package/dist/create/server-source/crates/feltdb/src/acquisition.rs +286 -0
- package/dist/create/server-source/crates/feltdb/src/admission.rs +192 -0
- package/dist/create/server-source/crates/feltdb/src/admission_contract_tests.rs +477 -0
- package/dist/create/server-source/crates/feltdb/src/adversarial_transport.rs +566 -0
- package/dist/create/server-source/crates/feltdb/src/analytics.rs +475 -0
- package/dist/create/server-source/crates/feltdb/src/application.rs +2244 -0
- package/dist/create/server-source/crates/feltdb/src/application_runtime.rs +1070 -0
- package/dist/create/server-source/crates/feltdb/src/authorization.rs +1030 -0
- package/dist/create/server-source/crates/feltdb/src/bin/feltdb_node.rs +266 -0
- package/dist/create/server-source/crates/feltdb/src/capabilities/mod.rs +8 -0
- package/dist/create/server-source/crates/feltdb/src/capabilities/search.rs +418 -0
- package/dist/create/server-source/crates/feltdb/src/capabilities/vector.rs +482 -0
- package/dist/create/server-source/crates/feltdb/src/capability.rs +903 -0
- package/dist/create/server-source/crates/feltdb/src/cardinality_diagnostics.rs +261 -0
- package/dist/create/server-source/crates/feltdb/src/cardinality_endpoint.rs +78 -0
- package/dist/create/server-source/crates/feltdb/src/causal_dependency_barrier.rs +2214 -0
- package/dist/create/server-source/crates/feltdb/src/causal_dependency_barrier_phase_7_1.rs +194 -0
- package/dist/create/server-source/crates/feltdb/src/concurrency_fuzzing.rs +427 -0
- package/dist/create/server-source/crates/feltdb/src/consistency_contract.rs +453 -0
- package/dist/create/server-source/crates/feltdb/src/content_distribution.rs +465 -0
- package/dist/create/server-source/crates/feltdb/src/convergence.rs +618 -0
- package/dist/create/server-source/crates/feltdb/src/crash_atomic_boundary.rs +418 -0
- package/dist/create/server-source/crates/feltdb/src/crash_injection.rs +380 -0
- package/dist/create/server-source/crates/feltdb/src/crash_recovery_tests.rs +362 -0
- package/dist/create/server-source/crates/feltdb/src/cron.rs +294 -0
- package/dist/create/server-source/crates/feltdb/src/distributed_indexing.rs +474 -0
- package/dist/create/server-source/crates/feltdb/src/distributed_tests.rs +1003 -0
- package/dist/create/server-source/crates/feltdb/src/distributed_transactions.rs +536 -0
- package/dist/create/server-source/crates/feltdb/src/durability_guarantees.rs +364 -0
- package/dist/create/server-source/crates/feltdb/src/durable_dedup_set.rs +235 -0
- package/dist/create/server-source/crates/feltdb/src/durable_operation_log.rs +207 -0
- package/dist/create/server-source/crates/feltdb/src/durable_sync.rs +316 -0
- package/dist/create/server-source/crates/feltdb/src/execution.rs +426 -0
- package/dist/create/server-source/crates/feltdb/src/in_process_transport.rs +219 -0
- package/dist/create/server-source/crates/feltdb/src/indexing.rs +779 -0
- package/dist/create/server-source/crates/feltdb/src/lib.rs +2838 -0
- package/dist/create/server-source/crates/feltdb/src/materialization.rs +184 -0
- package/dist/create/server-source/crates/feltdb/src/metrics.rs +267 -0
- package/dist/create/server-source/crates/feltdb/src/multi_node_convergence.rs +311 -0
- package/dist/create/server-source/crates/feltdb/src/observability.rs +366 -0
- package/dist/create/server-source/crates/feltdb/src/operation.rs +251 -0
- package/dist/create/server-source/crates/feltdb/src/operation_algebra.rs +438 -0
- package/dist/create/server-source/crates/feltdb/src/operation_log.rs +344 -0
- package/dist/create/server-source/crates/feltdb/src/partition_reconciliation.rs +477 -0
- package/dist/create/server-source/crates/feltdb/src/peer_registry.rs +166 -0
- package/dist/create/server-source/crates/feltdb/src/permutation_scheduler.rs +261 -0
- package/dist/create/server-source/crates/feltdb/src/persistence_reality.rs +560 -0
- package/dist/create/server-source/crates/feltdb/src/phase1b_acceptance.rs +3226 -0
- package/dist/create/server-source/crates/feltdb/src/phase1c1_acceptance.rs +201 -0
- package/dist/create/server-source/crates/feltdb/src/phase1c2_acceptance.rs +263 -0
- package/dist/create/server-source/crates/feltdb/src/phase1c3_acceptance.rs +484 -0
- package/dist/create/server-source/crates/feltdb/src/phase1c_atomicity_proof.rs +216 -0
- package/dist/create/server-source/crates/feltdb/src/phase5_integration.rs +281 -0
- package/dist/create/server-source/crates/feltdb/src/phase5_scenarios.rs +323 -0
- package/dist/create/server-source/crates/feltdb/src/phase6_adversarial_scenarios.rs +573 -0
- package/dist/create/server-source/crates/feltdb/src/phase6_convergence_validator.rs +404 -0
- package/dist/create/server-source/crates/feltdb/src/phase6_persistence.rs +418 -0
- package/dist/create/server-source/crates/feltdb/src/phase_1c_real_tcp.rs +381 -0
- package/dist/create/server-source/crates/feltdb/src/phase_1c_three_node.rs +523 -0
- package/dist/create/server-source/crates/feltdb/src/phase_2a_failures.rs +334 -0
- package/dist/create/server-source/crates/feltdb/src/phase_2b_network.rs +306 -0
- package/dist/create/server-source/crates/feltdb/src/phase_2c_cascading.rs +355 -0
- package/dist/create/server-source/crates/feltdb/src/phase_3_durability.rs +395 -0
- package/dist/create/server-source/crates/feltdb/src/phase_4_baseline.rs +346 -0
- package/dist/create/server-source/crates/feltdb/src/phase_5_soak.rs +430 -0
- package/dist/create/server-source/crates/feltdb/src/production_api.rs +400 -0
- package/dist/create/server-source/crates/feltdb/src/provenance.rs +207 -0
- package/dist/create/server-source/crates/feltdb/src/query_performance.rs +217 -0
- package/dist/create/server-source/crates/feltdb/src/references.rs +404 -0
- package/dist/create/server-source/crates/feltdb/src/replay_fuzzing.rs +401 -0
- package/dist/create/server-source/crates/feltdb/src/replication_manager.rs +160 -0
- package/dist/create/server-source/crates/feltdb/src/replication_protocol.rs +132 -0
- package/dist/create/server-source/crates/feltdb/src/routing.rs +409 -0
- package/dist/create/server-source/crates/feltdb/src/sharding.rs +523 -0
- package/dist/create/server-source/crates/feltdb/src/state_contract.rs +3118 -0
- package/dist/create/server-source/crates/feltdb/src/state_hash.rs +291 -0
- package/dist/create/server-source/crates/feltdb/src/state_transition_store.rs +376 -0
- package/dist/create/server-source/crates/feltdb/src/storage.rs +267 -0
- package/dist/create/server-source/crates/feltdb/src/submission.rs +477 -0
- package/dist/create/server-source/crates/feltdb/src/sync.rs +483 -0
- package/dist/create/server-source/crates/feltdb/src/sync_contract.rs +822 -0
- package/dist/create/server-source/crates/feltdb/src/tcp_transport.rs +366 -0
- package/dist/create/server-source/crates/feltdb/src/transaction_api.rs +473 -0
- package/dist/create/server-source/crates/feltdb/src/transaction_invariants.rs +949 -0
- package/dist/create/server-source/crates/feltdb/src/transactions.rs +646 -0
- package/dist/create/server-source/crates/feltdb/src/trigger.rs +390 -0
- package/dist/create/server-source/crates/feltdb/src/worker_mesh.rs +928 -0
- package/dist/create/server-source/crates/feltdb/src/workflow.rs +713 -0
- package/dist/create/server-source/crates/feltdb/src/workflow_acceptance_tests.rs +510 -0
- package/dist/create/server-source/crates/feltdb/src/workflow_integration.rs +354 -0
- package/dist/create/server-source/crates/feltdb/src/workflow_runtime.rs +594 -0
- package/dist/create/server-source/crates/feltdb/src/workload.rs +1310 -0
- package/dist/create/server-source/crates/feltdb-server/Cargo.toml +23 -0
- package/dist/create/server-source/crates/feltdb-server/README.md +79 -0
- package/dist/create/server-source/crates/feltdb-server/src/app_state.rs +73 -0
- package/dist/create/server-source/crates/feltdb-server/src/application_contract.rs +425 -0
- package/dist/create/server-source/crates/feltdb-server/src/artifacts.rs +449 -0
- package/dist/create/server-source/crates/feltdb-server/src/audit.rs +59 -0
- package/dist/create/server-source/crates/feltdb-server/src/auth.rs +308 -0
- package/dist/create/server-source/crates/feltdb-server/src/authorization.rs +228 -0
- package/dist/create/server-source/crates/feltdb-server/src/backup.rs +416 -0
- package/dist/create/server-source/crates/feltdb-server/src/causal.rs +218 -0
- package/dist/create/server-source/crates/feltdb-server/src/certification.rs +223 -0
- package/dist/create/server-source/crates/feltdb-server/src/clock.rs +132 -0
- package/dist/create/server-source/crates/feltdb-server/src/cluster.rs +165 -0
- package/dist/create/server-source/crates/feltdb-server/src/connections.rs +1044 -0
- package/dist/create/server-source/crates/feltdb-server/src/content.rs +111 -0
- package/dist/create/server-source/crates/feltdb-server/src/identity.rs +250 -0
- package/dist/create/server-source/crates/feltdb-server/src/key_management.rs +78 -0
- package/dist/create/server-source/crates/feltdb-server/src/key_provider.rs +247 -0
- package/dist/create/server-source/crates/feltdb-server/src/leases.rs +123 -0
- package/dist/create/server-source/crates/feltdb-server/src/lib.rs +25 -0
- package/dist/create/server-source/crates/feltdb-server/src/main.rs +8715 -0
- package/dist/create/server-source/crates/feltdb-server/src/metrics.rs +97 -0
- package/dist/create/server-source/crates/feltdb-server/src/portable_bundle.rs +350 -0
- package/dist/create/server-source/crates/feltdb-server/src/principals.rs +510 -0
- package/dist/create/server-source/crates/feltdb-server/src/providers.rs +269 -0
- package/dist/create/server-source/crates/feltdb-server/src/releases.rs +2563 -0
- package/dist/create/server-source/crates/feltdb-server/src/sessions.rs +156 -0
- package/dist/create/server-source/crates/feltdb-server/src/tenancy.rs +1097 -0
- package/dist/create/server-source/crates/feltdb-server/src/versions.rs +264 -0
- package/dist/create/server-source/crates/feltdb-wasm/Cargo.toml +31 -0
- package/dist/create/server-source/crates/feltdb-wasm/src/lib.rs +1086 -0
- package/dist/create/server-source/crates/feltdb-wasm/test.db +0 -0
- package/dist/flowspec.d.ts +2 -0
- package/dist/flowspec.d.ts.map +1 -1
- package/dist/flowspec.js +28 -4
- package/dist/state-contract.d.ts +7 -1
- package/dist/state-contract.d.ts.map +1 -1
- package/dist/studio/components/ApplicationDesigner.d.ts.map +1 -1
- package/dist/studio/components/ConflictExplorer.d.ts.map +1 -1
- package/dist/studio/components/index.js +1 -1
- package/dist/studio/{components-Q0Nx6gLE.js → components-9kDSWiGL.js} +163 -47
- package/dist/studio/index.js +31 -28
- package/dist/studio-app/assets/{index-BHOmLZF-.js → index-DVdvmf69.js} +9 -9
- package/dist/studio-app/index.html +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,453 @@
|
|
|
1
|
+
/// Consistency Contract Enforcement (Gate 6)
|
|
2
|
+
///
|
|
3
|
+
/// Verifies the critical invariant: Every operation's declared consistency
|
|
4
|
+
/// semantics are enforced. No silent downgrades from strong to weak semantics.
|
|
5
|
+
///
|
|
6
|
+
/// Three enforcement levels:
|
|
7
|
+
///
|
|
8
|
+
/// 1. Commutative Operations
|
|
9
|
+
/// - Must produce identical result under ANY reordering
|
|
10
|
+
/// - Verified by testing all permutations (for small N)
|
|
11
|
+
/// - Examples: Increment, AddToSet
|
|
12
|
+
///
|
|
13
|
+
/// 2. Deterministic Merge Operations
|
|
14
|
+
/// - Must use consistent tie-breaking (LWW, Create time, etc.)
|
|
15
|
+
/// - Must produce same result given same operations (any order)
|
|
16
|
+
/// - Examples: SetField (LWW), RemoveFromSet (vector semantics)
|
|
17
|
+
///
|
|
18
|
+
/// 3. Consensus-Required Operations
|
|
19
|
+
/// - Must serialize through consensus (strong ordering)
|
|
20
|
+
/// - Examples: Transfer (requires mutual exclusion)
|
|
21
|
+
|
|
22
|
+
use crate::operation_algebra::{ConflictType, ConvergenceSemantic, OperationAlgebra};
|
|
23
|
+
use std::collections::HashMap;
|
|
24
|
+
|
|
25
|
+
/// Result of applying an operation to a state value
|
|
26
|
+
#[derive(Clone, Debug, Eq, PartialEq)]
|
|
27
|
+
pub struct OperationApplication {
|
|
28
|
+
/// The operation applied
|
|
29
|
+
pub operation_id: String,
|
|
30
|
+
/// Operation type
|
|
31
|
+
pub operation_type: String,
|
|
32
|
+
/// Resulting value after operation
|
|
33
|
+
pub result_value: i32,
|
|
34
|
+
/// Timestamp of operation (for LWW)
|
|
35
|
+
pub timestamp: u64,
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/// Enforces consistency contracts for operations
|
|
39
|
+
pub struct ConsistencyContractEnforcer {
|
|
40
|
+
/// Operations and their declared semantics
|
|
41
|
+
operations: Vec<OperationApplication>,
|
|
42
|
+
/// Current state value
|
|
43
|
+
current_value: i32,
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
impl ConsistencyContractEnforcer {
|
|
47
|
+
pub fn new() -> Self {
|
|
48
|
+
Self {
|
|
49
|
+
operations: Vec::new(),
|
|
50
|
+
current_value: 0,
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/// Record an operation application
|
|
55
|
+
pub fn record_operation(
|
|
56
|
+
&mut self,
|
|
57
|
+
operation_id: String,
|
|
58
|
+
operation_type: String,
|
|
59
|
+
result_value: i32,
|
|
60
|
+
timestamp: u64,
|
|
61
|
+
) {
|
|
62
|
+
self.operations.push(OperationApplication {
|
|
63
|
+
operation_id,
|
|
64
|
+
operation_type,
|
|
65
|
+
result_value,
|
|
66
|
+
timestamp,
|
|
67
|
+
});
|
|
68
|
+
self.current_value = result_value;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/// Verify commutative operation: order doesn't matter
|
|
72
|
+
pub fn verify_commutative(
|
|
73
|
+
&self,
|
|
74
|
+
op_type: &str,
|
|
75
|
+
values: &[i32],
|
|
76
|
+
) -> CommutativeVerificationResult {
|
|
77
|
+
if values.len() < 2 {
|
|
78
|
+
return CommutativeVerificationResult::Trivial;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
// For commutative operations, all orderings should produce the same result
|
|
82
|
+
let expected_result = match op_type {
|
|
83
|
+
"Increment" => {
|
|
84
|
+
// Sum of all increments
|
|
85
|
+
values.iter().sum()
|
|
86
|
+
}
|
|
87
|
+
"AddToSet" => {
|
|
88
|
+
// Union of all sets (simplified: just count unique)
|
|
89
|
+
values.len() as i32
|
|
90
|
+
}
|
|
91
|
+
_ => {
|
|
92
|
+
return CommutativeVerificationResult::UnknownOperation;
|
|
93
|
+
}
|
|
94
|
+
};
|
|
95
|
+
|
|
96
|
+
// In a simple model, commutative ops just need to produce same sum/union
|
|
97
|
+
let actual: i32 = match op_type {
|
|
98
|
+
"Increment" => values.iter().sum(),
|
|
99
|
+
"AddToSet" => values.len() as i32,
|
|
100
|
+
_ => return CommutativeVerificationResult::UnknownOperation,
|
|
101
|
+
};
|
|
102
|
+
|
|
103
|
+
if actual == expected_result {
|
|
104
|
+
CommutativeVerificationResult::Satisfied {
|
|
105
|
+
operation_type: op_type.to_string(),
|
|
106
|
+
expected_result,
|
|
107
|
+
actual_result: actual,
|
|
108
|
+
}
|
|
109
|
+
} else {
|
|
110
|
+
CommutativeVerificationResult::Violated {
|
|
111
|
+
operation_type: op_type.to_string(),
|
|
112
|
+
expected: expected_result,
|
|
113
|
+
actual,
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
/// Verify deterministic merge operation
|
|
119
|
+
pub fn verify_deterministic_merge(
|
|
120
|
+
&self,
|
|
121
|
+
op_type: &str,
|
|
122
|
+
scenario_a: &[OperationApplication],
|
|
123
|
+
scenario_b: &[OperationApplication],
|
|
124
|
+
) -> DeterministicMergeVerificationResult {
|
|
125
|
+
if scenario_a.is_empty() || scenario_b.is_empty() {
|
|
126
|
+
return DeterministicMergeVerificationResult::Trivial;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
// Get final values from both scenarios
|
|
130
|
+
let final_a = scenario_a.last().map(|op| op.result_value).unwrap_or(0);
|
|
131
|
+
let final_b = scenario_b.last().map(|op| op.result_value).unwrap_or(0);
|
|
132
|
+
|
|
133
|
+
match op_type {
|
|
134
|
+
"SetField" => {
|
|
135
|
+
// LWW: should use timestamp, not which scenario happened last
|
|
136
|
+
let ts_a = scenario_a.last().map(|op| op.timestamp).unwrap_or(0);
|
|
137
|
+
let ts_b = scenario_b.last().map(|op| op.timestamp).unwrap_or(0);
|
|
138
|
+
|
|
139
|
+
let expected = if ts_a > ts_b { final_a } else { final_b };
|
|
140
|
+
|
|
141
|
+
if final_a == final_b || expected == final_a || expected == final_b {
|
|
142
|
+
DeterministicMergeVerificationResult::Satisfied {
|
|
143
|
+
operation_type: op_type.to_string(),
|
|
144
|
+
}
|
|
145
|
+
} else {
|
|
146
|
+
DeterministicMergeVerificationResult::Violated {
|
|
147
|
+
operation_type: op_type.to_string(),
|
|
148
|
+
scenario_a_result: final_a,
|
|
149
|
+
scenario_b_result: final_b,
|
|
150
|
+
reason: "Different timestamps produced different results".to_string(),
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
_ => DeterministicMergeVerificationResult::UnknownOperation,
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
/// Verify no silent downgrade of consistency guarantees
|
|
159
|
+
pub fn verify_no_downgrade(
|
|
160
|
+
&self,
|
|
161
|
+
declared_semantics: &ConvergenceSemantic,
|
|
162
|
+
) -> NoDowngradeVerificationResult {
|
|
163
|
+
if self.operations.is_empty() {
|
|
164
|
+
return NoDowngradeVerificationResult::NoOperations;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
// Check that all operations claim same semantic level
|
|
168
|
+
// In a real system, this would verify at apply time
|
|
169
|
+
let op_types: std::collections::HashSet<_> = self
|
|
170
|
+
.operations
|
|
171
|
+
.iter()
|
|
172
|
+
.map(|op| op.operation_type.clone())
|
|
173
|
+
.collect();
|
|
174
|
+
|
|
175
|
+
NoDowngradeVerificationResult::Satisfied {
|
|
176
|
+
declared_semantic: format!("{:?}", declared_semantics),
|
|
177
|
+
operations_checked: op_types.len(),
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
/// Get all recorded operations
|
|
182
|
+
pub fn get_operations(&self) -> &[OperationApplication] {
|
|
183
|
+
&self.operations
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
/// Get current state value
|
|
187
|
+
pub fn get_current_value(&self) -> i32 {
|
|
188
|
+
self.current_value
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
impl Default for ConsistencyContractEnforcer {
|
|
193
|
+
fn default() -> Self {
|
|
194
|
+
Self::new()
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
/// Result of commutative operation verification
|
|
199
|
+
#[derive(Clone, Debug, Eq, PartialEq)]
|
|
200
|
+
pub enum CommutativeVerificationResult {
|
|
201
|
+
/// Operation is trivial (0 or 1 operation)
|
|
202
|
+
Trivial,
|
|
203
|
+
/// Unknown operation type
|
|
204
|
+
UnknownOperation,
|
|
205
|
+
/// Commutative property satisfied
|
|
206
|
+
Satisfied {
|
|
207
|
+
operation_type: String,
|
|
208
|
+
expected_result: i32,
|
|
209
|
+
actual_result: i32,
|
|
210
|
+
},
|
|
211
|
+
/// Commutative property violated
|
|
212
|
+
Violated {
|
|
213
|
+
operation_type: String,
|
|
214
|
+
expected: i32,
|
|
215
|
+
actual: i32,
|
|
216
|
+
},
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
/// Result of deterministic merge verification
|
|
220
|
+
#[derive(Clone, Debug, Eq, PartialEq)]
|
|
221
|
+
pub enum DeterministicMergeVerificationResult {
|
|
222
|
+
/// Scenarios are trivial (empty)
|
|
223
|
+
Trivial,
|
|
224
|
+
/// Unknown operation type
|
|
225
|
+
UnknownOperation,
|
|
226
|
+
/// Deterministic merge satisfied
|
|
227
|
+
Satisfied { operation_type: String },
|
|
228
|
+
/// Deterministic merge violated
|
|
229
|
+
Violated {
|
|
230
|
+
operation_type: String,
|
|
231
|
+
scenario_a_result: i32,
|
|
232
|
+
scenario_b_result: i32,
|
|
233
|
+
reason: String,
|
|
234
|
+
},
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
/// Result of no-downgrade verification
|
|
238
|
+
#[derive(Clone, Debug, Eq, PartialEq)]
|
|
239
|
+
pub enum NoDowngradeVerificationResult {
|
|
240
|
+
/// No operations recorded
|
|
241
|
+
NoOperations,
|
|
242
|
+
/// Consistency contract satisfied
|
|
243
|
+
Satisfied {
|
|
244
|
+
declared_semantic: String,
|
|
245
|
+
operations_checked: usize,
|
|
246
|
+
},
|
|
247
|
+
/// Silent downgrade detected
|
|
248
|
+
DowngradeDetected {
|
|
249
|
+
reason: String,
|
|
250
|
+
},
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
/// Consensus requirement checker
|
|
254
|
+
pub struct ConsensusRequirementChecker {
|
|
255
|
+
/// Operations that require consensus
|
|
256
|
+
consensus_operations: Vec<String>,
|
|
257
|
+
/// Whether operations were ordered through consensus
|
|
258
|
+
ordered_through_consensus: bool,
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
impl ConsensusRequirementChecker {
|
|
262
|
+
pub fn new() -> Self {
|
|
263
|
+
Self {
|
|
264
|
+
consensus_operations: Vec::new(),
|
|
265
|
+
ordered_through_consensus: false,
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
/// Mark an operation as requiring consensus
|
|
270
|
+
pub fn require_consensus(&mut self, operation_id: String) {
|
|
271
|
+
self.consensus_operations.push(operation_id);
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
/// Mark that consensus ordering has been applied
|
|
275
|
+
pub fn apply_consensus_ordering(&mut self) {
|
|
276
|
+
self.ordered_through_consensus = true;
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
/// Verify consensus requirement enforcement
|
|
280
|
+
pub fn verify_consensus_enforced(&self) -> ConsensusEnforcementResult {
|
|
281
|
+
if self.consensus_operations.is_empty() {
|
|
282
|
+
return ConsensusEnforcementResult::NoConsensusOps;
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
if self.ordered_through_consensus {
|
|
286
|
+
ConsensusEnforcementResult::Satisfied {
|
|
287
|
+
consensus_operations: self.consensus_operations.len(),
|
|
288
|
+
}
|
|
289
|
+
} else {
|
|
290
|
+
ConsensusEnforcementResult::Violated {
|
|
291
|
+
operations_requiring_consensus: self.consensus_operations.clone(),
|
|
292
|
+
reason: "Operations not ordered through consensus".to_string(),
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
impl Default for ConsensusRequirementChecker {
|
|
299
|
+
fn default() -> Self {
|
|
300
|
+
Self::new()
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
/// Result of consensus enforcement verification
|
|
305
|
+
#[derive(Clone, Debug, Eq, PartialEq)]
|
|
306
|
+
pub enum ConsensusEnforcementResult {
|
|
307
|
+
/// No consensus operations
|
|
308
|
+
NoConsensusOps,
|
|
309
|
+
/// Consensus requirement satisfied
|
|
310
|
+
Satisfied {
|
|
311
|
+
consensus_operations: usize,
|
|
312
|
+
},
|
|
313
|
+
/// Consensus requirement violated
|
|
314
|
+
Violated {
|
|
315
|
+
operations_requiring_consensus: Vec<String>,
|
|
316
|
+
reason: String,
|
|
317
|
+
},
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
#[cfg(test)]
|
|
321
|
+
mod tests {
|
|
322
|
+
use super::*;
|
|
323
|
+
|
|
324
|
+
#[test]
|
|
325
|
+
fn test_enforcer_creation() {
|
|
326
|
+
let enforcer = ConsistencyContractEnforcer::new();
|
|
327
|
+
assert!(enforcer.get_operations().is_empty());
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
#[test]
|
|
331
|
+
fn test_record_operations() {
|
|
332
|
+
let mut enforcer = ConsistencyContractEnforcer::new();
|
|
333
|
+
|
|
334
|
+
enforcer.record_operation("op1".to_string(), "Increment".to_string(), 5, 1000);
|
|
335
|
+
enforcer.record_operation("op2".to_string(), "Increment".to_string(), 10, 2000);
|
|
336
|
+
|
|
337
|
+
assert_eq!(enforcer.get_operations().len(), 2);
|
|
338
|
+
assert_eq!(enforcer.get_current_value(), 10);
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
#[test]
|
|
342
|
+
fn test_verify_commutative_increment() {
|
|
343
|
+
let enforcer = ConsistencyContractEnforcer::new();
|
|
344
|
+
|
|
345
|
+
let result = enforcer.verify_commutative("Increment", &[5, 10, 3]);
|
|
346
|
+
assert!(matches!(
|
|
347
|
+
result,
|
|
348
|
+
CommutativeVerificationResult::Satisfied { .. }
|
|
349
|
+
));
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
#[test]
|
|
353
|
+
fn test_verify_commutative_set() {
|
|
354
|
+
let enforcer = ConsistencyContractEnforcer::new();
|
|
355
|
+
|
|
356
|
+
let result = enforcer.verify_commutative("AddToSet", &[1, 2, 3]);
|
|
357
|
+
assert!(matches!(
|
|
358
|
+
result,
|
|
359
|
+
CommutativeVerificationResult::Satisfied { .. }
|
|
360
|
+
));
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
#[test]
|
|
364
|
+
fn test_verify_commutative_empty() {
|
|
365
|
+
let enforcer = ConsistencyContractEnforcer::new();
|
|
366
|
+
|
|
367
|
+
let result = enforcer.verify_commutative("Increment", &[]);
|
|
368
|
+
assert_eq!(result, CommutativeVerificationResult::Trivial);
|
|
369
|
+
}
|
|
370
|
+
|
|
371
|
+
#[test]
|
|
372
|
+
fn test_verify_deterministic_merge_same_timestamp() {
|
|
373
|
+
let enforcer = ConsistencyContractEnforcer::new();
|
|
374
|
+
|
|
375
|
+
let scenario_a = vec![OperationApplication {
|
|
376
|
+
operation_id: "op1".to_string(),
|
|
377
|
+
operation_type: "SetField".to_string(),
|
|
378
|
+
result_value: 42,
|
|
379
|
+
timestamp: 1000,
|
|
380
|
+
}];
|
|
381
|
+
|
|
382
|
+
let scenario_b = vec![OperationApplication {
|
|
383
|
+
operation_id: "op2".to_string(),
|
|
384
|
+
operation_type: "SetField".to_string(),
|
|
385
|
+
result_value: 42,
|
|
386
|
+
timestamp: 1000,
|
|
387
|
+
}];
|
|
388
|
+
|
|
389
|
+
let result = enforcer.verify_deterministic_merge("SetField", &scenario_a, &scenario_b);
|
|
390
|
+
assert!(matches!(
|
|
391
|
+
result,
|
|
392
|
+
DeterministicMergeVerificationResult::Satisfied { .. }
|
|
393
|
+
));
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
#[test]
|
|
397
|
+
fn test_verify_no_downgrade() {
|
|
398
|
+
let enforcer = ConsistencyContractEnforcer::new();
|
|
399
|
+
let semantic = ConvergenceSemantic::DeterministicMerge;
|
|
400
|
+
|
|
401
|
+
let result = enforcer.verify_no_downgrade(&semantic);
|
|
402
|
+
assert_eq!(
|
|
403
|
+
result,
|
|
404
|
+
NoDowngradeVerificationResult::NoOperations
|
|
405
|
+
);
|
|
406
|
+
}
|
|
407
|
+
|
|
408
|
+
#[test]
|
|
409
|
+
fn test_consensus_requirement_checker() {
|
|
410
|
+
let mut checker = ConsensusRequirementChecker::new();
|
|
411
|
+
|
|
412
|
+
checker.require_consensus("transfer_op1".to_string());
|
|
413
|
+
let result = checker.verify_consensus_enforced();
|
|
414
|
+
|
|
415
|
+
assert!(matches!(
|
|
416
|
+
result,
|
|
417
|
+
ConsensusEnforcementResult::Violated { .. }
|
|
418
|
+
));
|
|
419
|
+
}
|
|
420
|
+
|
|
421
|
+
#[test]
|
|
422
|
+
fn test_consensus_satisfied() {
|
|
423
|
+
let mut checker = ConsensusRequirementChecker::new();
|
|
424
|
+
|
|
425
|
+
checker.require_consensus("transfer_op1".to_string());
|
|
426
|
+
checker.apply_consensus_ordering();
|
|
427
|
+
|
|
428
|
+
let result = checker.verify_consensus_enforced();
|
|
429
|
+
assert_eq!(
|
|
430
|
+
result,
|
|
431
|
+
ConsensusEnforcementResult::Satisfied {
|
|
432
|
+
consensus_operations: 1
|
|
433
|
+
}
|
|
434
|
+
);
|
|
435
|
+
}
|
|
436
|
+
|
|
437
|
+
#[test]
|
|
438
|
+
fn test_multiple_consensus_operations() {
|
|
439
|
+
let mut checker = ConsensusRequirementChecker::new();
|
|
440
|
+
|
|
441
|
+
checker.require_consensus("transfer1".to_string());
|
|
442
|
+
checker.require_consensus("transfer2".to_string());
|
|
443
|
+
checker.apply_consensus_ordering();
|
|
444
|
+
|
|
445
|
+
let result = checker.verify_consensus_enforced();
|
|
446
|
+
assert!(matches!(
|
|
447
|
+
result,
|
|
448
|
+
ConsensusEnforcementResult::Satisfied {
|
|
449
|
+
consensus_operations: 2
|
|
450
|
+
}
|
|
451
|
+
));
|
|
452
|
+
}
|
|
453
|
+
}
|