fix(carrier): C-02 — rolling dual-block manifest redundancy and failover recovery
This commit is contained in:
+43
-16
@@ -731,36 +731,63 @@ impl Database {
|
||||
],
|
||||
)?;
|
||||
|
||||
// Initialisiere CarrierManifest für Block 0
|
||||
// Initialisiere CarrierManifest für redundante Blöcke 0 und 1 (C-02)
|
||||
let manifest = crate::carrier::CarrierManifest::new(total_blocks);
|
||||
let manifest_bytes = serde_json::to_vec(&manifest)?;
|
||||
|
||||
let (inner_ct, inner_nonce, inner_tag) =
|
||||
// 1. Block 0 schreiben (Primärkopie, Gen 0)
|
||||
let (inner_ct_0, inner_nonce_0, inner_tag_0) =
|
||||
crate::crypto::encrypt_chunk(dek_1, c_id, 0, &manifest_bytes, FORMAT_VERSION, 0)?;
|
||||
let inner_ct_len = inner_ct.len() as u32;
|
||||
let inner_ct_len_0 = inner_ct_0.len() as u32;
|
||||
|
||||
let mut outer_plaintext = vec![0u8; CHUNK_SIZE];
|
||||
OsRng.fill_bytes(&mut outer_plaintext);
|
||||
let mut outer_plaintext_0 = vec![0u8; CHUNK_SIZE];
|
||||
OsRng.fill_bytes(&mut outer_plaintext_0);
|
||||
|
||||
outer_plaintext[0..12].copy_from_slice(&inner_nonce);
|
||||
outer_plaintext[12..28].copy_from_slice(&inner_tag);
|
||||
outer_plaintext[28..32].copy_from_slice(&inner_ct_len.to_le_bytes());
|
||||
let ct_end = 32 + inner_ct.len();
|
||||
if ct_end > CHUNK_SIZE {
|
||||
outer_plaintext_0[0..12].copy_from_slice(&inner_nonce_0);
|
||||
outer_plaintext_0[12..28].copy_from_slice(&inner_tag_0);
|
||||
outer_plaintext_0[28..32].copy_from_slice(&inner_ct_len_0.to_le_bytes());
|
||||
let ct_end_0 = 32 + inner_ct_0.len();
|
||||
if ct_end_0 > CHUNK_SIZE {
|
||||
bail!("Manifest-Payload zu groß für Block 0");
|
||||
}
|
||||
outer_plaintext[32..ct_end].copy_from_slice(&inner_ct);
|
||||
outer_plaintext_0[32..ct_end_0].copy_from_slice(&inner_ct_0);
|
||||
|
||||
let (outer_ct, outer_nonce, outer_tag) =
|
||||
crate::crypto::encrypt_chunk(dek_0, c_id, 0, &outer_plaintext, FORMAT_VERSION, 0)?;
|
||||
let (outer_ct_0, outer_nonce_0, outer_tag_0) =
|
||||
crate::crypto::encrypt_chunk(dek_0, c_id, 0, &outer_plaintext_0, FORMAT_VERSION, 0)?;
|
||||
|
||||
conn.execute(
|
||||
"INSERT INTO chunks (node_id, chunk_index, generation, nonce, tag, ciphertext)
|
||||
VALUES (?1, 0, 0, ?2, ?3, ?4)",
|
||||
params![c_id, outer_nonce.as_slice(), outer_tag.as_slice(), outer_ct],
|
||||
params![c_id, outer_nonce_0.as_slice(), outer_tag_0.as_slice(), outer_ct_0],
|
||||
)?;
|
||||
|
||||
// Blöcke 1..total_blocks-1 mit DEK_0 vorallokieren
|
||||
// 2. Block 1 schreiben (Redundante Zweitkopie, Gen 0, C-02)
|
||||
let (inner_ct_1, inner_nonce_1, inner_tag_1) =
|
||||
crate::crypto::encrypt_chunk(dek_1, c_id, 1, &manifest_bytes, FORMAT_VERSION, 0)?;
|
||||
let inner_ct_len_1 = inner_ct_1.len() as u32;
|
||||
|
||||
let mut outer_plaintext_1 = vec![0u8; CHUNK_SIZE];
|
||||
OsRng.fill_bytes(&mut outer_plaintext_1);
|
||||
|
||||
outer_plaintext_1[0..12].copy_from_slice(&inner_nonce_1);
|
||||
outer_plaintext_1[12..28].copy_from_slice(&inner_tag_1);
|
||||
outer_plaintext_1[28..32].copy_from_slice(&inner_ct_len_1.to_le_bytes());
|
||||
let ct_end_1 = 32 + inner_ct_1.len();
|
||||
if ct_end_1 > CHUNK_SIZE {
|
||||
bail!("Manifest-Payload zu groß für Block 1");
|
||||
}
|
||||
outer_plaintext_1[32..ct_end_1].copy_from_slice(&inner_ct_1);
|
||||
|
||||
let (outer_ct_1, outer_nonce_1, outer_tag_1) =
|
||||
crate::crypto::encrypt_chunk(dek_0, c_id, 1, &outer_plaintext_1, FORMAT_VERSION, 0)?;
|
||||
|
||||
conn.execute(
|
||||
"INSERT INTO chunks (node_id, chunk_index, generation, nonce, tag, ciphertext)
|
||||
VALUES (?1, 1, 0, ?2, ?3, ?4)",
|
||||
params![c_id, outer_nonce_1.as_slice(), outer_tag_1.as_slice(), outer_ct_1],
|
||||
)?;
|
||||
|
||||
// Blöcke 2..total_blocks-1 mit DEK_0 vorallokieren (C-02)
|
||||
let mut chunk_stmt = conn.prepare(
|
||||
"INSERT INTO chunks (node_id, chunk_index, generation, nonce, tag, ciphertext)
|
||||
VALUES (?1, ?2, 0, ?3, ?4, ?5)",
|
||||
@@ -770,7 +797,7 @@ impl Database {
|
||||
OsRng.fill_bytes(&mut dummy_noise);
|
||||
|
||||
conn.execute_batch("BEGIN TRANSACTION;")?;
|
||||
for b in 1..total_blocks {
|
||||
for b in 2..total_blocks {
|
||||
let (ct, nonce, tag) =
|
||||
crate::crypto::encrypt_chunk(dek_0, c_id, b, &dummy_noise, FORMAT_VERSION, 0)?;
|
||||
chunk_stmt.execute(params![c_id, b, nonce.as_slice(), tag.as_slice(), ct,])?;
|
||||
|
||||
Reference in New Issue
Block a user