feat: Implement DAG-based conflict resolution with binary keys and multi-head CLI display

This commit is contained in:
2025-12-22 01:56:26 +01:00
parent 346ebccee7
commit 57c2906b10
10 changed files with 950 additions and 240 deletions
+1
View File
@@ -41,4 +41,5 @@ pub use signed_entry::{EntryBuilder, sign_entry, verify_signed_entry, hash_signe
pub use log::{append_entry, read_entries, LogReader};
pub use store::Store;
pub use meta_store::MetaStore;
pub use proto::HeadInfo;
pub use uuid::Uuid;
+2 -1
View File
@@ -33,6 +33,7 @@ mod tests {
version: 1,
store_id: vec![1u8; 16],
prev_hash: vec![0u8; 32],
parent_hashes: vec![],
seq: 5,
timestamp: Some(Hlc {
wall_time: 1000,
@@ -41,7 +42,7 @@ mod tests {
ops: vec![
Operation {
op_type: Some(operation::OpType::Put(PutOp {
key: "/nodes/abc".to_string(),
key: b"/nodes/abc".to_vec(),
value: b"hello".to_vec(),
})),
},
+1 -1
View File
@@ -451,7 +451,7 @@ mod tests {
let ops = vec![
Operation {
op_type: Some(operation::OpType::Put(PutOp {
key: "/test".to_string(),
key: b"/test".to_vec(),
value: b"hello".to_vec(),
})),
},
+14 -5
View File
@@ -34,6 +34,7 @@ pub struct EntryBuilder {
version: u32,
store_id: Vec<u8>,
prev_hash: Vec<u8>,
parent_hashes: Vec<Vec<u8>>,
seq: u64,
timestamp: HLC,
ops: Vec<Operation>,
@@ -44,8 +45,9 @@ impl EntryBuilder {
pub fn new(seq: u64, timestamp: HLC) -> Self {
Self {
version: 1,
store_id: Vec::new(), // Empty = legacy single-store
prev_hash: vec![0u8; 32], // Genesis or will be set
store_id: Vec::new(),
prev_hash: vec![0u8; 32],
parent_hashes: Vec::new(),
seq,
timestamp,
ops: Vec::new(),
@@ -58,14 +60,20 @@ impl EntryBuilder {
self
}
/// Set the previous entry hash (for chaining)
/// Set the previous entry hash (for sigchain linking)
pub fn prev_hash(mut self, hash: impl Into<Vec<u8>>) -> Self {
self.prev_hash = hash.into();
self
}
/// Set the parent hashes (for DAG ancestry)
pub fn parent_hashes(mut self, hashes: Vec<Vec<u8>>) -> Self {
self.parent_hashes = hashes;
self
}
/// Add a Put operation
pub fn put(mut self, key: impl Into<String>, value: impl Into<Vec<u8>>) -> Self {
pub fn put(mut self, key: impl Into<Vec<u8>>, value: impl Into<Vec<u8>>) -> Self {
self.ops.push(Operation {
op_type: Some(operation::OpType::Put(PutOp {
key: key.into(),
@@ -76,7 +84,7 @@ impl EntryBuilder {
}
/// Add a Delete operation
pub fn delete(mut self, key: impl Into<String>) -> Self {
pub fn delete(mut self, key: impl Into<Vec<u8>>) -> Self {
self.ops.push(Operation {
op_type: Some(operation::OpType::Delete(DeleteOp {
key: key.into(),
@@ -97,6 +105,7 @@ impl EntryBuilder {
version: self.version,
store_id: self.store_id,
prev_hash: self.prev_hash,
parent_hashes: self.parent_hashes,
seq: self.seq,
timestamp: Some(Hlc {
wall_time: self.timestamp.wall_time,
+797 -190
View File
File diff suppressed because it is too large Load Diff